<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
  <meta name="theme-color" content="#222">
  <meta name="generator" content="Hexo 4.2.1">
  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/images/safari-pinned-tab.svg" color="#222">
  <link rel="stylesheet" href="/css/main.css">
  <link rel="stylesheet" href="/lib/font-awesome/css/all.min.css">
  <link rel="stylesheet" href="/lib/pace/pace-theme-minimal.min.css">
  <script src="/lib/pace/pace.min.js"></script>
  <script id="hexo-configurations">
    var NexT = window.NexT ||
    {};
    var CONFIG = {
      "hostname": "cuiqingcai.com",
      "root": "/",
      "scheme": "Pisces",
      "version": "7.8.0",
      "exturl": false,
      "sidebar":
      {
        "position": "right",
        "width": 360,
        "display": "post",
        "padding": 18,
        "offset": 12,
        "onmobile": false,
        "widgets": [
          {
            "type": "image",
            "name": "阿布云",
            "enable": false,
            "url": "https://www.abuyun.com/http-proxy/introduce.html",
            "src": "https://qiniu.cuiqingcai.com/88au8.jpg",
            "width": "100%"
      },
          {
            "type": "image",
            "name": "天验",
            "enable": true,
            "url": "https://tutorial.lengyue.video/?coupon=12ef4b1a-a3db-11ea-bb37-0242ac130002_cqx_850",
            "src": "https://qiniu.cuiqingcai.com/bco2a.png",
            "width": "100%"
      },
          {
            "type": "image",
            "name": "华为云",
            "enable": false,
            "url": "https://activity.huaweicloud.com/2020_618_promotion/index.html?bpName=5f9f98a29e2c40b780c1793086f29fe2&bindType=1&salesID=wangyubei",
            "src": "https://qiniu.cuiqingcai.com/y42ik.jpg",
            "width": "100%"
      },
          {
            "type": "image",
            "name": "张小鸡",
            "enable": false,
            "url": "http://www.zxiaoji.com/",
            "src": "https://qiniu.cuiqingcai.com/fm72f.png",
            "width": "100%"
      },
          {
            "type": "image",
            "name": "Luminati",
            "src": "https://qiniu.cuiqingcai.com/ikkq9.jpg",
            "url": "https://luminati-china.io/?affiliate=ref_5fbbaaa9647883f5c6f77095",
            "width": "100%",
            "enable": false
      },
          {
            "type": "image",
            "name": "IPIDEA",
            "url": "http://www.ipidea.net/?utm-source=cqc&utm-keyword=?cqc",
            "src": "https://qiniu.cuiqingcai.com/0ywun.png",
            "width": "100%",
            "enable": true
      },
          {
            "type": "tags",
            "name": "标签云",
            "enable": true
      },
          {
            "type": "categories",
            "name": "分类",
            "enable": true
      },
          {
            "type": "friends",
            "name": "友情链接",
            "enable": true
      },
          {
            "type": "hot",
            "name": "猜你喜欢",
            "enable": true
      }]
      },
      "copycode":
      {
        "enable": true,
        "show_result": true,
        "style": "mac"
      },
      "back2top":
      {
        "enable": true,
        "sidebar": false,
        "scrollpercent": true
      },
      "bookmark":
      {
        "enable": false,
        "color": "#222",
        "save": "auto"
      },
      "fancybox": false,
      "mediumzoom": false,
      "lazyload": false,
      "pangu": true,
      "comments":
      {
        "style": "tabs",
        "active": "gitalk",
        "storage": true,
        "lazyload": false,
        "nav": null,
        "activeClass": "gitalk"
      },
      "algolia":
      {
        "hits":
        {
          "per_page": 10
        },
        "labels":
        {
          "input_placeholder": "Search for Posts",
          "hits_empty": "We didn't find any results for the search: ${query}",
          "hits_stats": "${hits} results found in ${time} ms"
        }
      },
      "localsearch":
      {
        "enable": true,
        "trigger": "auto",
        "top_n_per_article": 10,
        "unescape": false,
        "preload": false
      },
      "motion":
      {
        "enable": false,
        "async": false,
        "transition":
        {
          "post_block": "bounceDownIn",
          "post_header": "slideDownIn",
          "post_body": "slideDownIn",
          "coll_header": "slideLeftIn",
          "sidebar": "slideUpIn"
        }
      },
      "path": "search.xml"
    };

  </script>
  <meta name="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
  <meta property="og:type" content="website">
  <meta property="og:title" content="静觅">
  <meta property="og:url" content="https://cuiqingcai.com/page/25/index.html">
  <meta property="og:site_name" content="静觅">
  <meta property="og:description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
  <meta property="og:locale" content="zh_CN">
  <meta property="article:author" content="崔庆才">
  <meta property="article:tag" content="崔庆才">
  <meta property="article:tag" content="静觅">
  <meta property="article:tag" content="PHP">
  <meta property="article:tag" content="Java">
  <meta property="article:tag" content="Python">
  <meta property="article:tag" content="Spider">
  <meta property="article:tag" content="爬虫">
  <meta property="article:tag" content="Web">
  <meta property="article:tag" content="Kubernetes">
  <meta property="article:tag" content="深度学习">
  <meta property="article:tag" content="机器学习">
  <meta property="article:tag" content="数据分析">
  <meta property="article:tag" content="网络">
  <meta property="article:tag" content="IT">
  <meta property="article:tag" content="技术">
  <meta property="article:tag" content="博客">
  <meta name="twitter:card" content="summary">
  <link rel="canonical" href="https://cuiqingcai.com/page/25/">
  <script id="page-configurations">
    // https://hexo.io/docs/variables.html
    CONFIG.page = {
      sidebar: "",
      isHome: true,
      isPost: false,
      lang: 'zh-CN'
    };

  </script>
  <title>静觅丨崔庆才的个人站点</title>
  <meta name="google-site-verification" content="p_bIcnvirkFzG2dYKuNDivKD8-STet5W7D-01woA2fc" />
  <noscript>
    <style>
      .use-motion .brand,
      .use-motion .menu-item,
      .sidebar-inner,
      .use-motion .post-block,
      .use-motion .pagination,
      .use-motion .comments,
      .use-motion .post-header,
      .use-motion .post-body,
      .use-motion .collection-header
      {
        opacity: initial;
      }

      .use-motion .site-title,
      .use-motion .site-subtitle
      {
        opacity: initial;
        top: initial;
      }

      .use-motion .logo-line-before i
      {
        left: initial;
      }

      .use-motion .logo-line-after i
      {
        right: initial;
      }

    </style>
  </noscript>
  <link rel="alternate" href="/atom.xml" title="静觅" type="application/atom+xml">
</head>

<body itemscope itemtype="http://schema.org/WebPage">
  <div class="container">
    <div class="headband"></div>
    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner">
        <div class="site-brand-container">
          <div class="site-nav-toggle">
            <div class="toggle" aria-label="切换导航栏">
              <span class="toggle-line toggle-line-first"></span>
              <span class="toggle-line toggle-line-middle"></span>
              <span class="toggle-line toggle-line-last"></span>
            </div>
          </div>
          <div class="site-meta">
            <a href="/" class="brand" rel="start">
              <span class="logo-line-before"><i></i></span>
              <h1 class="site-title">静觅 <span class="site-subtitle"> 崔庆才的个人站点 </span>
              </h1>
              <span class="logo-line-after"><i></i></span>
            </a>
          </div>
          <div class="site-nav-right">
            <div class="toggle popup-trigger">
              <i class="fa fa-search fa-fw fa-lg"></i>
            </div>
          </div>
        </div>
        <nav class="site-nav">
          <ul id="menu" class="main-menu menu">
            <li class="menu-item menu-item-home">
              <a href="/" rel="section">首页</a>
            </li>
            <li class="menu-item menu-item-archives">
              <a href="/archives/" rel="section">文章列表</a>
            </li>
            <li class="menu-item menu-item-tags">
              <a href="/tags/" rel="section">文章标签</a>
            </li>
            <li class="menu-item menu-item-categories">
              <a href="/categories/" rel="section">文章分类</a>
            </li>
            <li class="menu-item menu-item-about">
              <a href="/about/" rel="section">关于博主</a>
            </li>
            <li class="menu-item menu-item-message">
              <a href="/message/" rel="section">给我留言</a>
            </li>
            <li class="menu-item menu-item-search">
              <a role="button" class="popup-trigger">搜索 </a>
            </li>
          </ul>
        </nav>
        <div class="search-pop-overlay">
          <div class="popup search-popup">
            <div class="search-header">
              <span class="search-icon">
                <i class="fa fa-search"></i>
              </span>
              <div class="search-input-container">
                <input autocomplete="off" autocapitalize="off" placeholder="搜索..." spellcheck="false" type="search" class="search-input">
              </div>
              <span class="popup-btn-close">
                <i class="fa fa-times-circle"></i>
              </span>
            </div>
            <div id="search-result">
              <div id="no-result">
                <i class="fa fa-spinner fa-pulse fa-5x fa-fw"></i>
              </div>
            </div>
          </div>
        </div>
      </div>
    </header>
    <div class="back-to-top">
      <i class="fa fa-arrow-up"></i>
      <span>0%</span>
    </div>
    <div class="reading-progress-bar"></div>
    <main class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div class="content index posts-expand">
            <div class="carousel">
              <div id="wowslider-container">
                <div class="ws_images">
                  <ul>
                    <li><a target="_blank" href="https://cuiqingcai.com/5052.html"><img title="Python3网络爬虫开发实战教程" src="https://qiniu.cuiqingcai.com/ipy96.jpg" /></a></li>
                    <li><a target="_blank" href="https://t.lagou.com/fRCBRsRCSN6FA"><img title="52讲轻松搞定网络爬虫" src="https://qiniu.cuiqingcai.com/fqq5e.png" /></a></li>
                    <li><a target="_blank" href="https://brightdata.grsm.io/cuiqingcai"><img title="亮网络解锁器" src="https://qiniu.cuiqingcai.com/6qnb7.png" /></a></li>
                    <li><a target="_blank" href="https://cuiqingcai.com/4320.html"><img title="Python3网络爬虫开发视频教程" src="https://qiniu.cuiqingcai.com/bjrny.jpg" /></a></li>
                    <li><a target="_blank" href="https://cuiqingcai.com/5094.html"><img title="爬虫代理哪家强？十大付费代理详细对比评测出炉！" src="https://qiniu.cuiqingcai.com/nifs6.jpg" /></a></li>
                  </ul>
                </div>
                <div class="ws_thumbs">
                  <div>
                    <a target="_blank" href="#"><img src="https://qiniu.cuiqingcai.com/ipy96.jpg" /></a>
                    <a target="_blank" href="#"><img src="https://qiniu.cuiqingcai.com/fqq5e.png" /></a>
                    <a target="_blank" href="#"><img src="https://qiniu.cuiqingcai.com/6qnb7.png" /></a>
                    <a target="_blank" href="#"><img src="https://qiniu.cuiqingcai.com/bjrny.jpg" /></a>
                    <a target="_blank" href="#"><img src="https://qiniu.cuiqingcai.com/nifs6.jpg" /></a>
                  </div>
                </div>
                <div class="ws_shadow"></div>
              </div>
            </div>
            <link rel="stylesheet" href="/lib/wowslide/slide.css">
            <script src="/lib/wowslide/jquery.min.js"></script>
            <script src="/lib/wowslide/slider.js"></script>
            <script>
              jQuery("#wowslider-container").wowSlider(
              {
                effect: "cube",
                prev: "",
                next: "",
                duration: 20 * 100,
                delay: 20 * 100,
                width: 716,
                height: 297,
                autoPlay: true,
                playPause: true,
                stopOnHover: false,
                loop: false,
                bullets: 0,
                caption: true,
                captionEffect: "slide",
                controls: true,
                onBeforeStep: 0,
                images: 0
              });

            </script>
            <article itemscope itemtype="http://schema.org/Article" class="post-block index" lang="zh-CN">
              <link itemprop="mainEntityOfPage" href="https://cuiqingcai.com/2185.html">
              <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
                <meta itemprop="image" content="/images/avatar.png">
                <meta itemprop="name" content="崔庆才">
                <meta itemprop="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
              </span>
              <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
                <meta itemprop="name" content="静觅">
              </span>
              <header class="post-header">
                <h2 class="post-title" itemprop="name headline">
                  <a class="label"> HTML <i class="label-arrow"></i>
                  </a>
                  <a href="/2185.html" class="post-title-link" itemprop="url">HTML5中Device Orientation的特性</a>
                </h2>
              </header>
              <div class="post-body" itemprop="articleBody">
                <div class="thumb">
                  <img itemprop="contentUrl" class="random">
                </div>
                <div class="excerpt">
                  <p>
                  <p>HTML5中包含一个帮助检测device orientation的特性，使用这个特性可以在移动设备浏览器中判断用户设备的旋转重力方向。</p>
                  <h2 id="基本知识"><a href="#基本知识" class="headerlink" title="基本知识"></a>基本知识</h2>
                  <p>Alpha, Beta, Gamma角度旋转。 当用户旋转手机的时候，HTML5中定义了三个轴方向的旋转，如下： <a href="http://www.gbtags.com/gb/networks/uploadimg/48ca06d6-fef5-4c18-9379-a49b6b9db3af.png" target="_blank" rel="noopener"><img src="http://www.gbtags.com/gb/networks/uploadimgthumb/48ca06d6-fef5-4c18-9379-a49b6b9db3af.png" alt=""></a> 上图可以看考，分别是z，x，y轴，对应分别是：Alpha，Beta，Gamma，下面图将更清楚的展示： <a href="http://www.gbtags.com/gb/networks/uploadimg/13a73e08-da9a-47a0-be1d-9d8dea6c2f98.png" target="_blank" rel="noopener"><img src="http://www.gbtags.com/gb/networks/uploadimgthumb/13a73e08-da9a-47a0-be1d-9d8dea6c2f98.png" alt=""></a> 上图是Alpha旋转，　围绕Z轴旋转（绿线旋转方向，水平） <img src="http://www.gbtags.com/gb/networks/uploadimgthumb/3803a433-29b7-48e8-8abe-b9c48270047c.png" alt=""> 上图是Beta旋转，　围绕X轴旋转（绿线旋转方向，前后） <img src="http://www.gbtags.com/gb/networks/uploadimgthumb/cbb478f5-4490-48f1-af44-0b9e73844057.png" alt=""> 上图是Beta旋转，　围绕Y轴旋转（绿线旋转方向，左右）</p>
                  <h2 id="属性"><a href="#属性" class="headerlink" title="属性"></a>属性</h2>
                  <ul>
                    <li>alpha: <em>(float 类型 )</em>以z方向为轴心的旋转角度 浮点数类型，只读属性，取值范围为0到360（不等于360）。</li>
                    <li>beta: <em>(float 类型 )</em>以x方向为轴心的旋转角度 浮点数类型，只读属性，取值范围为-180到180（不等于180）。</li>
                    <li>gamma: <em>(float 类型 )</em>以y方向为轴心的旋转角度 浮点数类型，只读属性，取值范围为-180到180（不等于180）。</li>
                  </ul>
                  <h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2>
                  <p><a href="http://www.gbtags.com/gb/share/4247.htm" target="_blank" rel="noopener">原文链接</a></p>
                  </p>
                </div>
              </div>
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-user"></i>
                  </span>
                  <span class="post-meta-item-text">作者</span>
                  <span><a href="/authors/崔庆才" class="author" itemprop="url" rel="index">崔庆才</a></span>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>
                  <time title="创建时间：2015-10-28 19:24:09" itemprop="dateCreated datePublished" datetime="2015-10-28T19:24:09+08:00">2015-10-28</time>
                </span>
                <span id="/2185.html" class="post-meta-item leancloud_visitors" data-flag-title="HTML5中Device Orientation的特性" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="fa fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
                <span class="post-meta-item" title="本文字数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-file-word"></i>
                  </span>
                  <span class="post-meta-item-text">本文字数：</span>
                  <span>440</span>
                </span>
                <span class="post-meta-item" title="阅读时长">
                  <span class="post-meta-item-icon">
                    <i class="far fa-clock"></i>
                  </span>
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                  <span>1 分钟</span>
                </span>
              </div>
            </article>
            <article itemscope itemtype="http://schema.org/Article" class="post-block index" lang="zh-CN">
              <link itemprop="mainEntityOfPage" href="https://cuiqingcai.com/2138.html">
              <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
                <meta itemprop="image" content="/images/avatar.png">
                <meta itemprop="name" content="崔庆才">
                <meta itemprop="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
              </span>
              <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
                <meta itemprop="name" content="静觅">
              </span>
              <header class="post-header">
                <h2 class="post-title" itemprop="name headline">
                  <a class="label"> Net <i class="label-arrow"></i>
                  </a>
                  <a href="/2138.html" class="post-title-link" itemprop="url">计算机网络探究二之利用PHP实现登录验证之后上网</a>
                </h2>
              </header>
              <div class="post-body" itemprop="articleBody">
                <div class="thumb">
                  <img itemprop="contentUrl" class="random">
                </div>
                <div class="excerpt">
                  <p>
                  <h2 id="综述"><a href="#综述" class="headerlink" title="综述"></a>综述</h2>
                  <p>在上一篇文章中，客户机可以借助路由机直接上网，并没有什么登录限制。接下来我们将加入上网登录验证，只有输入了正确的用户名和密码才可以通过验证，然后才可以访问互联网。 接下来，就跟随我用PHP来实现登录验证吧。</p>
                  <h2 id="环境配置"><a href="#环境配置" class="headerlink" title="环境配置"></a>环境配置</h2>
                  <p>在这之前，你需要配置一下LAMP环境，也就是Apache，MySQL，PHP开发环境，依次执行如下命令即可。</p>
                  <figure class="highlight smali">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">sudo apt-get install apache2</span><br><span class="line">sudo apt-get install php5 php5-cgi php5-mysql php5-curl php5-gd php5-idn php-pear php5-imagick php5-imap php5-mcrypt php5-memcache php5-mhash php5-ming php5-pspell php5-recode php5-snmp php5-tidy php5-xmlrpc php5-sqlite php5-xsl</span><br><span class="line">sudo apt-get install mysql-server mysql-client</span><br><span class="line">sudo apt-get install libapache2-mod-php5</span><br><span class="line">sudo apt-get install libapache2-mod-auth-mysql</span><br><span class="line">sudo apt-get install phpmyadmin</span><br><span class="line">sudo ln -s /usr/share/phpmyadmin/ /var/www/html/phpmyadmin</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>如果配置出现问题，请查阅相关资料。 apache默认的目录为 /var/www/html，我们这时访问 <a href="http://localhost" target="_blank" rel="noopener">localhost</a> 或者 <a href="http://192.168.122.4" target="_blank" rel="noopener">192.168.122.4</a>，都可以出现apache的欢迎界面，就证明我们配置成功了。</p>
                  <h2 id="路由初始设置"><a href="#路由初始设置" class="headerlink" title="路由初始设置"></a>路由初始设置</h2>
                  <p>为了在登录之前限制主机的上网，我们需要利用iptables规则来对数据包的转发加以限制。同时，将网页重定向到本机的登录界面。 初始路由设置如下</p>
                  <figure class="highlight routeros">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">iptables -F</span><br><span class="line">iptables -t<span class="built_in"> nat </span>-F</span><br><span class="line">iptables -t<span class="built_in"> mangle </span>-F</span><br><span class="line">iptables -P INPUT ACCEPT</span><br><span class="line">iptables -P FORWARD ACCEPT</span><br><span class="line">iptables -t<span class="built_in"> nat </span>-A POSTROUTING -o eth0 -j MASQUERADE</span><br><span class="line">iptables -t<span class="built_in"> filter </span>-A FORWARD -s 192.168.122.0/24 -o eth0 -j REJECT</span><br><span class="line">iptables -t<span class="built_in"> filter </span>-A FORWARD -s 192.168.122.0/24 -d 119.29.29.29/32 -j ACCEPT</span><br><span class="line">iptables -t<span class="built_in"> nat </span>-A PREROUTING -s 192.168.122.0/24 -p tcp -j DNAT --to 192.168.122.4</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>首先清除所有的iptables规则，然后设置前一篇我们说的IP伪装，这时可以客户机可以通过主机上网。 接下来的一条规则则禁用了来自 192.168.122.0 网段的所有IP的数据包转发，然后设置可访问DNS服务器，最后一条则设置了所有的tcp连接自动跳转到 192.168.122.4，也就是我们刚才配置的服务器。 可以把以上规则保存为脚本，比如叫 init.sh 来运行，也可以添加到 /etc/rc.local 中，开机自动运行。</p>
                  <h2 id="登录页面"><a href="#登录页面" class="headerlink" title="登录页面"></a>登录页面</h2>
                  <p>访问到192.168.122.4时，我们需要给用户呈现的当然不是刚才显示的apache欢迎页面，而是登录的输入框以及登录按钮界面。 所以，登录界面代码如下</p>
                  <figure class="highlight xml">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="meta">&lt;!DOCTYPE <span class="meta-keyword">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span> <span class="attr">lang</span>=<span class="string">"zh-CN"</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">"utf-8"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">meta</span> <span class="attr">http-equiv</span>=<span class="string">"X-UA-Compatible"</span> <span class="attr">content</span>=<span class="string">"IE=edge"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">meta</span> <span class="attr">name</span>=<span class="string">"viewport"</span> <span class="attr">content</span>=<span class="string">"width=device-width, initial-scale=1"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">title</span>&gt;</span>Auth Login<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!-- Bootstrap --&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">link</span> <span class="attr">rel</span>=<span class="string">"stylesheet"</span> <span class="attr">href</span>=<span class="string">"css/bootstrap.min.css"</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">form</span> <span class="attr">id</span>=<span class="string">"auth"</span> <span class="attr">method</span>=<span class="string">"post"</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"input-group"</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">span</span> <span class="attr">class</span>=<span class="string">"input-group-addon"</span> <span class="attr">id</span>=<span class="string">"basic-addon1"</span>&gt;</span>Username<span class="tag">&lt;/<span class="name">span</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">"text"</span> <span class="attr">class</span>=<span class="string">"form-control"</span> <span class="attr">placeholder</span>=<span class="string">"Username"</span> <span class="attr">aria-describedby</span>=<span class="string">"basic-addon1"</span> <span class="attr">name</span>=<span class="string">"username"</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"input-group"</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">span</span> <span class="attr">class</span>=<span class="string">"input-group-addon"</span> <span class="attr">id</span>=<span class="string">"basic-addon1"</span>&gt;</span>Password<span class="tag">&lt;/<span class="name">span</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">"text"</span> <span class="attr">class</span>=<span class="string">"form-control"</span> <span class="attr">placeholder</span>=<span class="string">"Password"</span> <span class="attr">aria-describedby</span>=<span class="string">"basic-addon1"</span> <span class="attr">name</span>=<span class="string">"password"</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">"button"</span> <span class="attr">id</span>=<span class="string">"login"</span> <span class="attr">class</span>=<span class="string">"btn btn-primary"</span> <span class="attr">value</span>=<span class="string">"Login"</span>&gt;</span></span><br><span class="line">	  <span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">"button"</span> <span class="attr">id</span>=<span class="string">"logout"</span> <span class="attr">class</span>=<span class="string">"btn btn-primary"</span> <span class="attr">value</span>=<span class="string">"Logout"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">form</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!-- jQuery (necessary for Bootstrap's JavaScript plugins) --&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">"js/jquery.min.js"</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!-- Include all compiled plugins (below), or include individual files as needed --&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">"js/bootstrap.min.js"</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">style</span>&gt;</span></span><br><span class="line">    form &#123;</span><br><span class="line"><span class="css">      <span class="selector-tag">max-width</span><span class="selector-pseudo">:400px</span>;</span></span><br><span class="line"><span class="css">      <span class="selector-tag">margin</span><span class="selector-pseudo">:0</span> <span class="selector-tag">auto</span>;</span></span><br><span class="line">    &#125;</span><br><span class="line"><span class="css">    <span class="selector-class">.input-group</span> &#123;</span></span><br><span class="line"><span class="css">      <span class="selector-tag">margin-bottom</span><span class="selector-pseudo">:20px</span>;</span></span><br><span class="line">    &#125;</span><br><span class="line">  <span class="tag">&lt;/<span class="name">style</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="javascript">	$(<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span></span><br><span class="line"><span class="javascript">		$(<span class="string">"#login"</span>).on(<span class="string">"click"</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span></span><br><span class="line"><span class="javascript">			$(<span class="string">"#auth"</span>).attr(<span class="string">"action"</span>, <span class="string">"/login.php"</span>);</span></span><br><span class="line"><span class="javascript">			$(<span class="string">"#auth"</span>).submit();</span></span><br><span class="line">		&#125;);</span><br><span class="line"><span class="javascript">		$(<span class="string">"#logout"</span>).on(<span class="string">"click"</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span></span><br><span class="line"><span class="javascript">			$(<span class="string">"#auth"</span>).attr(<span class="string">"action"</span>, <span class="string">"/logout.php"</span>);</span></span><br><span class="line"><span class="javascript">			$(<span class="string">"#auth"</span>).submit();</span></span><br><span class="line">		&#125;);</span><br><span class="line">	&#125;);</span><br><span class="line">  <span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>其中的js，jquery文件请大家自行引入。 预览一下效果 <a href="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/10/20151008151728.png" target="_blank" rel="noopener"><img src="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/10/20151008151728.png" alt="20151008151728"></a> 在这里我们设置了两个按钮，一个是登录，一个是下线。</p>
                  <h2 id="数据库查询验证"><a href="#数据库查询验证" class="headerlink" title="数据库查询验证"></a>数据库查询验证</h2>
                  <p>接下来我们新建一个数据库，例如我新建了一个数据库叫auth，然后数据表user，里面有三个字段。分别是id，username，password，我插入了一条数据。 <a href="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/10/20151008152059.png" target="_blank" rel="noopener"><img src="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/10/20151008152059.png" alt="20151008152059"></a> 接下来我们就尝试一下登录，提交到 login.php 文件验证一下。</p>
                  <figure class="highlight xml">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="php"><span class="meta">&lt;?php</span></span></span><br><span class="line"><span class="php">	$mysql_server_name = <span class="string">"localhost"</span>;</span></span><br><span class="line"><span class="php">	$mysql_username = <span class="string">"root"</span>;</span></span><br><span class="line"><span class="php">	$mysql_password = <span class="string">"123456"</span>;</span></span><br><span class="line"><span class="php">	$mysql_database = <span class="string">"auth"</span>; </span></span><br><span class="line"><span class="php">	$username = @$_POST[<span class="string">'username'</span>];</span></span><br><span class="line"><span class="php">	$password = @$_POST[<span class="string">'password'</span>];</span></span><br><span class="line"><span class="php">	$ip=$_SERVER[<span class="string">"REMOTE_ADDR"</span>];	</span></span><br><span class="line"><span class="php">	$conn=mysql_connect($mysql_server_name, $mysql_username,</span></span><br><span class="line"><span class="php">                        $mysql_password);</span></span><br><span class="line"><span class="php">	<span class="keyword">if</span> ($conn) &#123;</span></span><br><span class="line"><span class="php">		$sql = <span class="string">"select * from user where username = '"</span>.$username.<span class="string">"'"</span>;</span></span><br><span class="line"><span class="php">		$result = mysql_fetch_array(mysql_db_query($mysql_database, $sql, $conn));</span></span><br><span class="line"><span class="php">		<span class="keyword">if</span> ($result) &#123;</span></span><br><span class="line"><span class="php">			<span class="keyword">if</span> ($result[<span class="string">'password'</span>] == $password) &#123;</span></span><br><span class="line"><span class="php">				$status = <span class="number">-1</span>;</span></span><br><span class="line"><span class="php">				system(<span class="string">"sudo ./bash/login.sh $ip"</span>, $status);</span></span><br><span class="line"><span class="php">				<span class="keyword">if</span> ($status == <span class="number">0</span>) &#123;</span></span><br><span class="line"><span class="php">					<span class="keyword">echo</span> <span class="string">"Login Successfully"</span>;				</span></span><br><span class="line"><span class="php">				&#125; <span class="keyword">else</span> &#123;</span></span><br><span class="line"><span class="php">					<span class="keyword">echo</span> <span class="string">"Login Failed"</span>;</span></span><br><span class="line"><span class="php">				&#125;</span></span><br><span class="line"><span class="php">			&#125; <span class="keyword">else</span> &#123;</span></span><br><span class="line"><span class="php">				<span class="keyword">echo</span> <span class="string">"Wrong Password"</span>;</span></span><br><span class="line"><span class="php">			&#125;	</span></span><br><span class="line"><span class="php">		&#125; <span class="keyword">else</span> &#123;</span></span><br><span class="line"><span class="php">			<span class="keyword">echo</span> <span class="string">"Not"</span>;</span></span><br><span class="line"><span class="php">		&#125;</span></span><br><span class="line"><span class="php">	&#125; <span class="keyword">else</span> &#123;</span></span><br><span class="line"><span class="php">		<span class="keyword">die</span>(<span class="string">"Could Not Connect"</span>);</span></span><br><span class="line"><span class="php">	&#125;</span></span><br><span class="line"><span class="php"><span class="meta">?&gt;</span></span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>其中，最重要的部分莫过于</p>
                  <figure class="highlight perl">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="keyword">system</span>(<span class="string">"sudo ./bash/login.sh $ip"</span>, $status);</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>这一行代码了，此处便是登录验证用户名和密码之后执行的一个 Linux 脚本命令。 在这里我把要执行的脚本写入了login.sh文件中，传入的参数便是ip地址。 那么login.sh里面发生了什么事情呢，我们来看一下。</p>
                  <figure class="highlight routeros">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">iptables -t<span class="built_in"> nat </span>-D PREROUTING -s <span class="variable">$1</span>/32 -j ACCEPT</span><br><span class="line">iptables -t<span class="built_in"> nat </span>-D PREROUTING -s <span class="variable">$1</span>/32 -p tcp -j ACCEPT</span><br><span class="line">iptables -t<span class="built_in"> filter </span>-D FORWARD -s <span class="variable">$1</span>/32 -o eth0 -j ACCEPT</span><br><span class="line">iptables -t<span class="built_in"> nat </span>-I PREROUTING -s <span class="variable">$1</span>/32 -j ACCEPT</span><br><span class="line">iptables -t<span class="built_in"> nat </span>-I PREROUTING -s <span class="variable">$1</span>/32 -p tcp -j ACCEPT</span><br><span class="line">iptables -t<span class="built_in"> filter </span>-I FORWARD -s <span class="variable">$1</span>/32 -o eth0 -j ACCEPT</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>$1的意思就是获取第一个参数，在这里就是IP地址，脚本主要做的事情就是放行来自这个IP地址的数据包，让其正常访问互联网。 保存脚本后，记得给脚本赋予权限</p>
                  <figure class="highlight angelscript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">sudo chmod <span class="number">777</span> login.sh</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>-D的意思就是删除，因为iptables是可以添加多次相同的规则的，在添加之前删除一下，以防止多次添加。 在这里</p>
                  <figure class="highlight armasm">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="symbol">sudo</span> ./<span class="keyword">bash/login.sh </span>$<span class="built_in">ip</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>执行命令脚本前，我们加了sudo，意思就是管理员身份运行，但是仍然可能导致权限问题，因为命令的执行者是PHP（其实是www-data），而并不是root用户，所以我们需要修改一下执行权限。 首先通过PHP文件获取执行该命令的用户是叫什么，比如新建一个 info.php 文件，输入如下内容：</p>
                  <figure class="highlight xml">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="php"><span class="meta">&lt;?php</span> </span></span><br><span class="line"><span class="php">    <span class="keyword">echo</span> shell_exec(<span class="string">"id -a"</span>);</span></span><br><span class="line"><span class="php"><span class="meta">?&gt;</span></span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>看一下运行结果 <a href="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/10/20151008153424.png" target="_blank" rel="noopener"><img src="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/10/20151008153424.png" alt="20151008153424"></a> 嗯，果然，执行用户是www-data，这样我们只需要给www-data添加一个执行权限就好了。 修改 /etc/sudoers 文件 添加一行</p>
                  <figure class="highlight fortran">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">www-<span class="keyword">data</span> <span class="built_in">ALL</span>=(<span class="built_in">ALL</span>) NOPASSWD:<span class="built_in">ALL</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>意思是www-data以root身份运行并且不需要密码。 <a href="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/10/20151008153700.png" target="_blank" rel="noopener"><img src="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/10/20151008153700.png" alt="20151008153700"></a> 好，保存之后，我们尝试一下，就可以登录啦。</p>
                  <h2 id="测试登录"><a href="#测试登录" class="headerlink" title="测试登录"></a>测试登录</h2>
                  <p>在路由主机（Ubuntu Route）里面，初始化一下iptables规则，然后查看当前规则。 我们发现当前访问都是被阻止的，而且tcp连接会自动跳转到 192.168.122.4 <a href="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/10/20151008154216.png" target="_blank" rel="noopener"><img src="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/10/20151008154216.png" alt="20151008154216"></a> 现在我们登录客户机，随机打开一个网址，比如百度，就发现自动跳转到了登录界面 <a href="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/10/20151008154629.png" target="_blank" rel="noopener"><img src="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/10/20151008154629.png" alt="20151008154629"></a> 输入用户名密码，尝试登陆，比如之前插入数据库的是cqc，123456，输入之后登录。 <a href="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/10/20151008162712.png" target="_blank" rel="noopener"><img src="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/10/20151008162712.png" alt="20151008162712"></a> 提示登录成功之后，我们便可以欢乐地上网啦。 <a href="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/10/20151008162926.png" target="_blank" rel="noopener"><img src="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/10/20151008162926.png" alt="20151008162926"></a> 好，这样我们就完成了验证之后上网啦。</p>
                  <h2 id="下线操作"><a href="#下线操作" class="headerlink" title="下线操作"></a>下线操作</h2>
                  <p>同样的，下线操作我们同样写一个logout.php</p>
                  <figure class="highlight xml">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="php"><span class="meta">&lt;?php</span></span></span><br><span class="line"><span class="php">	$mysql_server_name = <span class="string">"localhost"</span>;</span></span><br><span class="line"><span class="php">	$mysql_username = <span class="string">"root"</span>;</span></span><br><span class="line"><span class="php">	$mysql_password = <span class="string">"123456"</span>;</span></span><br><span class="line"><span class="php">	$mysql_database = <span class="string">"auth"</span>; </span></span><br><span class="line"><span class="php">	$username = @$_POST[<span class="string">'username'</span>];</span></span><br><span class="line"><span class="php">	$password = @$_POST[<span class="string">'password'</span>];</span></span><br><span class="line"><span class="php">	$ip=$_SERVER[<span class="string">"REMOTE_ADDR"</span>];</span></span><br><span class="line"><span class="php">	<span class="keyword">echo</span> $ip;	</span></span><br><span class="line"><span class="php">	$conn=mysql_connect($mysql_server_name, $mysql_username,</span></span><br><span class="line"><span class="php">                        $mysql_password);</span></span><br><span class="line"><span class="php">	<span class="keyword">if</span> ($conn) &#123;</span></span><br><span class="line"><span class="php">		$sql = <span class="string">"select * from user where username = '"</span>.$username.<span class="string">"'"</span>;</span></span><br><span class="line"><span class="php">		$result = mysql_fetch_array(mysql_db_query($mysql_database, $sql, $conn));</span></span><br><span class="line"><span class="php">		<span class="keyword">if</span> ($result) &#123;</span></span><br><span class="line"><span class="php">			<span class="keyword">if</span> ($result[<span class="string">'password'</span>] == $password) &#123;</span></span><br><span class="line"><span class="php">				$status = <span class="number">-1</span>;</span></span><br><span class="line"><span class="php">				system(<span class="string">"sudo ./bash/logout.sh $ip"</span>, $status);</span></span><br><span class="line"><span class="php">				<span class="keyword">if</span> ($status == <span class="number">0</span>) &#123;</span></span><br><span class="line"><span class="php">					<span class="keyword">echo</span> <span class="string">"Login Successfully"</span>;				</span></span><br><span class="line"><span class="php">				&#125; <span class="keyword">else</span> &#123;</span></span><br><span class="line"><span class="php">					<span class="keyword">echo</span> <span class="string">"Login Failed"</span>;</span></span><br><span class="line"><span class="php">				&#125;</span></span><br><span class="line"><span class="php">			&#125; <span class="keyword">else</span> &#123;</span></span><br><span class="line"><span class="php">				<span class="keyword">echo</span> <span class="string">"Wrong Password"</span>;</span></span><br><span class="line"><span class="php">			&#125;	</span></span><br><span class="line"><span class="php">		&#125; <span class="keyword">else</span> &#123;</span></span><br><span class="line"><span class="php">			<span class="keyword">echo</span> <span class="string">"Not"</span>;</span></span><br><span class="line"><span class="php">		&#125;</span></span><br><span class="line"><span class="php">	&#125; <span class="keyword">else</span> &#123;</span></span><br><span class="line"><span class="php">		<span class="keyword">die</span>(<span class="string">"Could Not Connect"</span>);</span></span><br><span class="line"><span class="php">	&#125;</span></span><br><span class="line"><span class="php"><span class="meta">?&gt;</span></span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>登出的脚本如下，其实就是单纯去除了刚才添加的路由规则</p>
                  <figure class="highlight routeros">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">iptables -t<span class="built_in"> nat </span>-D PREROUTING -s <span class="variable">$1</span>/32 -j ACCEPT</span><br><span class="line">iptables -t<span class="built_in"> nat </span>-D PREROUTING -s <span class="variable">$1</span>/32 -p tcp -j ACCEPT</span><br><span class="line">iptables -t<span class="built_in"> filter </span>-D FORWARD -s <span class="variable">$1</span>/32 -o eth0 -j ACCEPT</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>配置方式和登录一样，大家可以尝试下。</p>
                  <h2 id="源代码"><a href="#源代码" class="headerlink" title="源代码"></a>源代码</h2>
                  <p>在这里提供大家源代码下载 <a href="https://github.com/cqcre/PHPLogin" target="_blank" rel="noopener">源码下载</a> 如有问题，欢迎交流。</p>
                  </p>
                </div>
              </div>
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-user"></i>
                  </span>
                  <span class="post-meta-item-text">作者</span>
                  <span><a href="/authors/崔庆才" class="author" itemprop="url" rel="index">崔庆才</a></span>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>
                  <time title="创建时间：2015-10-08 00:27:44" itemprop="dateCreated datePublished" datetime="2015-10-08T00:27:44+08:00">2015-10-08</time>
                </span>
                <span id="/2138.html" class="post-meta-item leancloud_visitors" data-flag-title="计算机网络探究二之利用PHP实现登录验证之后上网" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="fa fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
                <span class="post-meta-item" title="本文字数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-file-word"></i>
                  </span>
                  <span class="post-meta-item-text">本文字数：</span>
                  <span>6.3k</span>
                </span>
                <span class="post-meta-item" title="阅读时长">
                  <span class="post-meta-item-icon">
                    <i class="far fa-clock"></i>
                  </span>
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                  <span>6 分钟</span>
                </span>
              </div>
            </article>
            <article itemscope itemtype="http://schema.org/Article" class="post-block index" lang="zh-CN">
              <link itemprop="mainEntityOfPage" href="https://cuiqingcai.com/2126.html">
              <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
                <meta itemprop="image" content="/images/avatar.png">
                <meta itemprop="name" content="崔庆才">
                <meta itemprop="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
              </span>
              <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
                <meta itemprop="name" content="静觅">
              </span>
              <header class="post-header">
                <h2 class="post-title" itemprop="name headline">
                  <a class="label"> Net <i class="label-arrow"></i>
                  </a>
                  <a href="/2126.html" class="post-title-link" itemprop="url">计算机网络探究一之利用双网卡主机共享上网</a>
                </h2>
              </header>
              <div class="post-body" itemprop="articleBody">
                <div class="thumb">
                  <img itemprop="contentUrl" class="random">
                </div>
                <div class="excerpt">
                  <p>
                  <h2 id="综述"><a href="#综述" class="headerlink" title="综述"></a>综述</h2>
                  <p>大家好，这次我们需要实现的是实现双网卡主机共享上网，就是一台主机通过连接另一台可以访问外网的双网卡主机来正常上网。所以我们需要两台机器来进行测试，在这里我们用的是两台Ubuntu 14.04，其中一台是单网卡，一台是双网卡。废话不多说，行动起来吧。</p>
                  <h2 id="配置系统"><a href="#配置系统" class="headerlink" title="配置系统"></a>配置系统</h2>
                  <p>博主使用了Vmware来安装了两台Ubuntu主机，一台当路由机，名称是Ubuntu Route，另一台是客户机，名称是Ubuntu Desktop，具体的网络配置如下： Ubuntu Route： 一个网卡eth0通过NAT方式来与外部主机共享上网，这个网卡也就是VMnet8网卡，网段是192.168.231.0 <a href="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/10/20151007164043.png" target="_blank" rel="noopener"><img src="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/10/20151007164043.png" alt="20151007164043"></a> 另一个网卡eth1连接了一个自定义的仅主机模式的网卡VMnet2，网段是192.168.122.0 <a href="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/10/20151007164114.png" target="_blank" rel="noopener"><img src="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/10/20151007164114.png" alt="20151007164114"></a> 网络适配器设置如下，eth0开启了DHCP，ech1没有开启DHCP <a href="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/10/20151007164343.png" target="_blank" rel="noopener"><img src="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/10/20151007164343.png" alt="20151007164343"></a> Ubuntu Desktop： 一个网卡eth0连接刚才那个自定义的仅主机模式的网卡VMnet2，网段是192.168.122.0 <a href="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/10/20151007164821.png" target="_blank" rel="noopener"><img src="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/10/20151007164821.png" alt="20151007164821"></a> 好了，以上就是基本硬件的配置</p>
                  <h2 id="设置IP"><a href="#设置IP" class="headerlink" title="设置IP"></a>设置IP</h2>
                  <p>接下来我们设置一下Ubuntu Route的IP地址，修改 /etc/network/interfaces</p>
                  <figure class="highlight routeros">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">auto lo</span><br><span class="line">iface lo inet loopback</span><br><span class="line">auto eth0</span><br><span class="line">iface eth0 inet dhcp</span><br><span class="line">auto eth1</span><br><span class="line">iface eth1 inet static</span><br><span class="line">address 192.168.122.4</span><br><span class="line">netmask 255.255.255.0</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>在这里，eth0因为我们在VMware里面设置了DHCP，所以这里我们设置dhcp即可，eth1需要手动配置一下，我们分配了 192.168.122.4 这个IP地址，当然你可以随意指定，子网掩码如上，不需要写网关，因为它本身作为一个路由。 可以通过执行如下命令来使之生效</p>
                  <figure class="highlight awk">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">sudo <span class="regexp">/etc/i</span>nit.d<span class="regexp">/networking restart</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>如果上述方法不行，则可以尝试使用关闭网卡和开启网卡的命令。</p>
                  <figure class="highlight properties">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="attr">sudo</span> <span class="string">ifup eth0</span></span><br><span class="line"><span class="attr">sudo</span> <span class="string">ifdown eth0</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>eth1的开启和关闭同上</p>
                  <h2 id="开启路由转发"><a href="#开启路由转发" class="headerlink" title="开启路由转发"></a>开启路由转发</h2>
                  <p>修改 /etc/sysctl.conf 文件，将</p>
                  <figure class="highlight ini">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="attr">net.ipv4.ip_forward</span>=<span class="number">1</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>这一行取消注释，代表开启了路由转发功能。 也可以通过执行</p>
                  <figure class="highlight awk">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">echo <span class="number">1</span> &gt; <span class="regexp">/proc/</span>sys<span class="regexp">/net/i</span>pv4<span class="regexp">/ip_forward</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>命令来实现</p>
                  <h2 id="设置iptables规则"><a href="#设置iptables规则" class="headerlink" title="设置iptables规则"></a>设置iptables规则</h2>
                  <p>iptables是非常重要的一个环节，如果大家不熟悉，可以去搜相关资料了解一下。 执行如下命令，来设置一下iptables规则，可以直接在命令行逐条执行，也可以写成一个脚本来执行。</p>
                  <figure class="highlight routeros">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">iptables -F</span><br><span class="line">iptables -t<span class="built_in"> nat </span>-F</span><br><span class="line">iptables -t<span class="built_in"> mangle </span>-F</span><br><span class="line">iptables -P INPUT ACCEPT</span><br><span class="line">iptables -P FORWARD ACCEPT</span><br><span class="line">iptables -t<span class="built_in"> nat </span>-A POSTROUTING -o eth0 -j MASQUERADE</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>其中最后一条是最重要的，代表将数据包通过eth0网卡来转发，也是IP伪装的一个常用方法，有了这条指令，从eth1网卡流经的一些数据包可以通过eth0来转发，这样就相当于连通了两个网卡，这样与eth1网卡连接的主机便可以上网了。</p>
                  <h2 id="客户主机设置"><a href="#客户主机设置" class="headerlink" title="客户主机设置"></a>客户主机设置</h2>
                  <p>因为客户机的eth0连接了VMnet2网卡，而VMnet2网卡又与路由主机的eth1连接，我们只需要简单设置一下IP地址就好了。 修改 /etc/network/interfaces</p>
                  <figure class="highlight angelscript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="built_in">auto</span> eth0</span><br><span class="line">iface eth0 inet static</span><br><span class="line">address <span class="number">192.168</span><span class="number">.122</span><span class="number">.5</span></span><br><span class="line">netmask <span class="number">255.255</span><span class="number">.255</span><span class="number">.0</span></span><br><span class="line">gateway <span class="number">192.168</span><span class="number">.122</span><span class="number">.4</span></span><br><span class="line">dns-nameservers <span class="number">119.29</span><span class="number">.29</span><span class="number">.29</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>这里很重要的一个设置就是网关，设置成路由主机的IP地址。 设置完了同样重启一下网卡使其生效。 还可以选择性设置下DNS服务器。 至此，所有配置都完成了，测试一下吧。</p>
                  <h2 id="测试"><a href="#测试" class="headerlink" title="测试"></a>测试</h2>
                  <p>我们在客户机里打开浏览器，输入随意一个网页测试一下。 <a href="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/10/20151007172000.png" target="_blank" rel="noopener"><img src="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/10/20151007172000.png" alt="20151007172000"></a> 嗯，客户机可以正常上网啦，一切都是那么轻松加愉快！ 如有问题，欢迎留言交流~</p>
                  </p>
                </div>
              </div>
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-user"></i>
                  </span>
                  <span class="post-meta-item-text">作者</span>
                  <span><a href="/authors/崔庆才" class="author" itemprop="url" rel="index">崔庆才</a></span>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>
                  <time title="创建时间：2015-10-07 17:23:37" itemprop="dateCreated datePublished" datetime="2015-10-07T17:23:37+08:00">2015-10-07</time>
                </span>
                <span id="/2126.html" class="post-meta-item leancloud_visitors" data-flag-title="计算机网络探究一之利用双网卡主机共享上网" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="fa fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
                <span class="post-meta-item" title="本文字数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-file-word"></i>
                  </span>
                  <span class="post-meta-item-text">本文字数：</span>
                  <span>1.7k</span>
                </span>
                <span class="post-meta-item" title="阅读时长">
                  <span class="post-meta-item-icon">
                    <i class="far fa-clock"></i>
                  </span>
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                  <span>2 分钟</span>
                </span>
              </div>
            </article>
            <article itemscope itemtype="http://schema.org/Article" class="post-block index" lang="zh-CN">
              <link itemprop="mainEntityOfPage" href="https://cuiqingcai.com/2083.html">
              <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
                <meta itemprop="image" content="/images/avatar.png">
                <meta itemprop="name" content="崔庆才">
                <meta itemprop="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
              </span>
              <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
                <meta itemprop="name" content="静觅">
              </span>
              <header class="post-header">
                <h2 class="post-title" itemprop="name headline">
                  <a class="label"> Python <i class="label-arrow"></i>
                  </a>
                  <a href="/2083.html" class="post-title-link" itemprop="url">Python爬虫实战三之实现山东大学无线网络掉线自动重连</a>
                </h2>
              </header>
              <div class="post-body" itemprop="articleBody">
                <div class="thumb">
                  <img itemprop="contentUrl" class="random">
                </div>
                <div class="excerpt">
                  <p>
                  <h2 id="综述"><a href="#综述" class="headerlink" title="综述"></a>综述</h2>
                  <p>最近山大软件园校区QLSC_STU无线网掉线掉的厉害，连上之后平均十分钟左右掉线一次，很是让人心烦，还能不能愉快地上自习了？能忍吗？反正我是不能忍了，嗯，自己动手，丰衣足食！写个程序解决掉它！ 假若你不能连这个无线，那就照照思路啦～</p>
                  <h2 id="决战前夕"><a href="#决战前夕" class="headerlink" title="决战前夕"></a>决战前夕</h2>
                  <p>首先我们看一下那个验证页面是咋样滴，上个图先 <a href="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/09/20150920192557.png" target="_blank" rel="noopener"><img src="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/09/20150920192557.png" alt="20150920192557"></a> 嘿，这界面还算可以把，需要我们输入的东西就是俩，一个就是学号，另一个是身份证号后六位，然后就可以登录，享受免费的无线网啦。 不过不知道谁设置了个登录时长，一段时间后就会掉线了，于是，自动模拟登陆系统就要应运而生啦。 来，我们先点击一下连接，看一下浏览器怎么工作的。 按下F12，监听网络，我们点击第一个响应，也就是login.jsp，看一下。 <a href="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/09/20150920192957.png" target="_blank" rel="noopener"><img src="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/09/20150920192957-1024x661.png" alt="20150920192957"></a> 我们具体看一下headers，里面form提交了什么东西，真的是茫茫多的数据啊。 <a href="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/09/20150920193146.png" target="_blank" rel="noopener"><img src="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/09/20150920193146.png" alt="20150920193146"></a> 嗯，一目了然POST的数据和提交的地址。 让我们来分析几个数据吧：</p>
                  <blockquote>
                    <p>ClientIP：当前客户端的IP地址，在山大软件园校区这个地址是211.87开头的</p>
                    <p>timeoutvalue：连接等待时间，也就是俗话说的timeout</p>
                    <p>StartTime：登录时间，也就是在你登录的那一刻的时间戳，这个时间戳是13位的，精确到了毫秒，不过一般是10位的，我们加3个0就好了</p>
                    <p>shkOvertime：登录持续时间，这个数据默认是720，也就是12分钟之后，登录就失效了，自动掉线，我们可以手动更改</p>
                    <p>username：学号</p>
                    <p>password：密码，也就是我们身份证号后六位</p>
                  </blockquote>
                  <p>我们需要在登录的时候把form表单中的所有信息都POST一下，然后就可以完成登录啦。 万事俱备，只欠东风，来来来，程序写起来！</p>
                  <h2 id="一触即发"><a href="#一触即发" class="headerlink" title="一触即发"></a>一触即发</h2>
                  <p>说走咱就走啊，天上的星星参北斗啊！ 登陆地址：Request URL:<a href="http://192.168.8.10/portal/login.jsp?Flag=0" target="_blank" rel="noopener">http://192.168.8.10/portal/login.jsp?Flag=0</a> 首先，我们需要验证一下IP地址，先写一个获取IP地址的函数，首先判断当前IP是不是211.87开头的，如果是的话，证明连接的IP是有效的。 首先我们写一个获取本机IP的方法：</p>
                  <figure class="highlight properties">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="meta">self.ip_pre</span> = <span class="string">"211.87"    </span></span><br><span class="line"><span class="comment">#获取本机无线IP</span></span><br><span class="line">    <span class="attr">def</span> <span class="string">getIP(self):</span></span><br><span class="line">        <span class="attr">local_iP</span> = <span class="string">socket.gethostbyname(socket.gethostname())</span></span><br><span class="line">        <span class="attr">if</span> <span class="string">self.ip_pre in str(local_iP):</span></span><br><span class="line">            <span class="attr">return</span> <span class="string">str(local_iP)</span></span><br><span class="line">        <span class="attr">ip_lists</span> = <span class="string">socket.gethostbyname_ex(socket.gethostname())</span></span><br><span class="line"></span><br><span class="line">        <span class="attr">for</span> <span class="string">ip_list in ip_lists:</span></span><br><span class="line">            <span class="attr">if</span> <span class="string">isinstance(ip_list, list):</span></span><br><span class="line">                <span class="attr">for</span> <span class="string">i in ip_list:</span></span><br><span class="line">                    <span class="attr">if</span> <span class="string">self.ip_pre in str(i):</span></span><br><span class="line">                        <span class="attr">return</span> <span class="string">str(i)</span></span><br><span class="line">            <span class="attr">elif</span> <span class="string">type(ip_list) is types.StringType:</span></span><br><span class="line">                <span class="attr">if</span> <span class="string">self.ip_pre in ip_list:</span></span><br><span class="line">                    <span class="attr">return</span> <span class="string">ip_list</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>这个方法利用了gethostbyname和gethostbyname_ex方法，获取了各个网卡的IP地址，遍历一下，找到那个211.87开头的IP，返回 接下来，获取到IP之后，我们便可以构建form，然后进行模拟登陆了。</p>
                  <figure class="highlight ruby">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="comment">#模拟登录</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">login</span><span class="params">(<span class="keyword">self</span>)</span></span><span class="symbol">:</span></span><br><span class="line">        print <span class="keyword">self</span>.getCurrentTime(), u<span class="string">"正在尝试认证QLSC_STU无线网络"</span></span><br><span class="line">        ip = <span class="keyword">self</span>.getIP()</span><br><span class="line">        data = &#123;</span><br><span class="line">            <span class="string">"username"</span>: <span class="keyword">self</span>.username,</span><br><span class="line">            <span class="string">"password"</span>: <span class="keyword">self</span>.password,</span><br><span class="line">            <span class="string">"serverType"</span>: <span class="string">""</span>,</span><br><span class="line">            <span class="string">"isSavePass"</span>: <span class="string">"on"</span>,</span><br><span class="line">            <span class="string">"Submit1"</span>: <span class="string">""</span>,</span><br><span class="line">            <span class="string">"Language"</span>: <span class="string">"Chinese"</span>,</span><br><span class="line">            <span class="string">"ClientIP"</span>: <span class="keyword">self</span>.getIP(),</span><br><span class="line">            <span class="string">"timeoutvalue"</span>: <span class="number">45</span>,</span><br><span class="line">            <span class="string">"heartbeat"</span>: <span class="number">240</span>,</span><br><span class="line">            <span class="string">"fastwebornot"</span>: False,</span><br><span class="line">            <span class="string">"StartTime"</span>: <span class="keyword">self</span>.getNowTime(),</span><br><span class="line">            <span class="comment">#持续时间，超过这个时间自动掉线，可进行设置</span></span><br><span class="line">            <span class="string">"shkOvertime"</span>: <span class="keyword">self</span>.overtime,</span><br><span class="line">            <span class="string">"strOSName"</span>: <span class="string">""</span>,</span><br><span class="line">            <span class="string">"iAdptIndex"</span>: <span class="string">""</span>,</span><br><span class="line">            <span class="string">"strAdptName"</span>: <span class="string">""</span>,</span><br><span class="line">            <span class="string">"strAdptStdName"</span>: <span class="string">""</span>,</span><br><span class="line">            <span class="string">"strFileEncoding"</span>: <span class="string">""</span>,</span><br><span class="line">            <span class="string">"PhysAddr"</span>: <span class="string">""</span>,</span><br><span class="line">            <span class="string">"bDHCPEnabled"</span>: <span class="string">""</span>,</span><br><span class="line">            <span class="string">"strIPAddrArray"</span>: <span class="string">""</span>,</span><br><span class="line">            <span class="string">"strMaskArray"</span>: <span class="string">""</span>,</span><br><span class="line">            <span class="string">"strMask"</span>: <span class="string">""</span>,</span><br><span class="line">            <span class="string">"iDHCPDelayTime"</span>: <span class="string">""</span>,</span><br><span class="line">            <span class="string">"iDHCPTryTimes"</span>: <span class="string">""</span>,</span><br><span class="line">            <span class="string">"strOldPrivateIP"</span>: <span class="keyword">self</span>.getIP(),</span><br><span class="line">            <span class="string">"strOldPublicIP"</span>: <span class="keyword">self</span>.getIP(),</span><br><span class="line">            <span class="string">"strPrivateIP"</span>: <span class="keyword">self</span>.getIP(),</span><br><span class="line">            <span class="string">"PublicIP"</span>: <span class="keyword">self</span>.getIP(),</span><br><span class="line">            <span class="string">"iIPCONFIG"</span><span class="symbol">:</span><span class="number">0</span>,</span><br><span class="line">            <span class="string">"sHttpPrefix"</span>: <span class="string">"http://192.168.8.10"</span>,</span><br><span class="line">            <span class="string">"title"</span>: <span class="string">"CAMS Portal"</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">#消息头</span></span><br><span class="line">        headers = &#123;</span><br><span class="line">            <span class="string">'User-Agent'</span> : <span class="string">'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36'</span>,</span><br><span class="line">            <span class="string">'Host'</span>: <span class="string">'192.168.8.10'</span>,</span><br><span class="line">            <span class="string">'Origin'</span>: <span class="string">'http://192.168.8.10'</span>,</span><br><span class="line">            <span class="string">'Referer'</span>: <span class="string">'http://192.168.8.10/portal/index_default.jsp?Language=Chinese'</span></span><br><span class="line">        &#125;</span><br><span class="line">        post_data = urllib.urlencode(data)</span><br><span class="line">        login_url = <span class="string">"http://192.168.8.10/portal/login.jsp?Flag=0"</span></span><br><span class="line">        request = urllib2.Request(login_url, post_data, headers)</span><br><span class="line">        response = urllib2.urlopen(request)</span><br><span class="line">        result = response.read().decode(<span class="string">'gbk'</span>)</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>比较多的内容就在于form表单的数据内容以及请求头，后来利用urllib2的urlopen方法实现模拟登陆。 如果大家对此不熟悉，可以参见 <a href="http://cuiqingcai.com/947.html">Urllib的基本使用</a> 这样，登录后的结果就会保存在result变量中，我们只需要从result中提取出我们需要的数据就可以了。</p>
                  <h2 id="乘胜追击"><a href="#乘胜追击" class="headerlink" title="乘胜追击"></a>乘胜追击</h2>
                  <p>接下来，我们就分析一下数据啦，结果有这么几种：</p>
                  <blockquote>
                    <p>1.登录成功 2.已经登录 3.用户不存在 4.密码错误 5.未知错误</p>
                  </blockquote>
                  <p>好，利用result分析一下结果</p>
                  <figure class="highlight python">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="comment">#打印登录结果</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">getLoginResult</span><span class="params">(self, result)</span>:</span></span><br><span class="line">        <span class="keyword">if</span> <span class="string">u"用户上线成功"</span> <span class="keyword">in</span> result:</span><br><span class="line">            <span class="keyword">print</span> self.getCurrentTime(),<span class="string">u"用户上线成功,在线时长为"</span>,self.overtime/<span class="number">60</span>,<span class="string">"分钟"</span></span><br><span class="line">        <span class="keyword">elif</span> <span class="string">u"您已经建立了连接"</span> <span class="keyword">in</span> result:</span><br><span class="line">            <span class="keyword">print</span> self.getCurrentTime(),<span class="string">u"您已经建立了连接,无需重复登陆"</span></span><br><span class="line">        <span class="keyword">elif</span> <span class="string">u"用户不存在"</span> <span class="keyword">in</span> result:</span><br><span class="line">            <span class="keyword">print</span> self.getCurrentTime(),<span class="string">u"用户不存在，请检查学号是否正确"</span></span><br><span class="line">        <span class="keyword">elif</span> <span class="string">u"用户密码错误"</span> <span class="keyword">in</span> result:</span><br><span class="line">            pattern = re.compile(<span class="string">'&lt;td class="tWhite"&gt;.*?2553:(.*?)&lt;/b&gt;.*?&lt;/td&gt;'</span>, re.S)</span><br><span class="line">            res = re.search(pattern, result)</span><br><span class="line">            <span class="keyword">if</span> res:</span><br><span class="line">                <span class="keyword">print</span> self.getCurrentTime(),res.group(<span class="number">1</span>),<span class="string">u"请重新修改密码"</span></span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            <span class="keyword">print</span> self.getCurrentTime(),<span class="string">u"未知错误，请检查学号密码是否正确"</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>通过字符串匹配和正则表达式，我们分辨并提取出了上述五种情况。 增加循环检测 既然是检测网络是否断开，那么我们只需要每隔一段时间检测一下就好了，那就10秒吧。 因为这个10秒是可配置的，为了方便配置，统一配置到<strong>init</strong>方法里面。</p>
                  <figure class="highlight ini">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="comment">#检测间隔时间，单位为秒</span></span><br><span class="line"><span class="attr">self.every</span> = <span class="number">10</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>然后，我们写一个循环来检测一下</p>
                  <figure class="highlight python">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line">            nowIP = self.getIP()</span><br><span class="line">            <span class="keyword">if</span> <span class="keyword">not</span> nowIP:</span><br><span class="line">                <span class="keyword">print</span> self.getCurrentTime(), <span class="string">u"请检查是否正常连接QLSC_STU无线网络"</span></span><br><span class="line">            <span class="keyword">else</span>:</span><br><span class="line">                <span class="keyword">print</span> self.getCurrentTime(),<span class="string">u"成功连接了QLSC_STU网络,本机IP为"</span>,nowIP</span><br><span class="line">                self.login()</span><br><span class="line">                <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line">                    can_connect = self.canConnect()</span><br><span class="line">                    <span class="keyword">if</span> <span class="keyword">not</span> can_connect:</span><br><span class="line">                        nowIP = self.getIP()</span><br><span class="line">                        <span class="keyword">if</span> <span class="keyword">not</span> nowIP:</span><br><span class="line">                            <span class="keyword">print</span> self.getCurrentTime(), <span class="string">u"当前已经断线，请确保连接上了QLSC_STU网络"</span></span><br><span class="line">                        <span class="keyword">else</span>:</span><br><span class="line">                            <span class="keyword">print</span> self.getCurrentTime(), <span class="string">u"当前已经断线，正在尝试重新连接"</span></span><br><span class="line">                            self.login()</span><br><span class="line">                    <span class="keyword">else</span>:</span><br><span class="line">                        <span class="keyword">print</span> self.getCurrentTime(), <span class="string">u"当前网络连接正常"</span></span><br><span class="line">                    time.sleep(self.every)</span><br><span class="line">            time.sleep(self.every)</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>其中我们用到了canConnect方法，这个就是检测网络是否已经断开的方法，我们可以利用ping百度的方法来检测一下。 方法实现如下</p>
                  <figure class="highlight livecodeserver">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="comment">#判断当前是否可以联网</span></span><br><span class="line">    def canConnect(self):</span><br><span class="line">        fnull = <span class="built_in">open</span>(os.devnull, <span class="string">'w'</span>)</span><br><span class="line">        <span class="built_in">result</span> = subprocess.call(<span class="string">'ping www.baidu.com'</span>, <span class="built_in">shell</span> = True, <span class="keyword">stdout</span> = fnull, <span class="keyword">stderr</span> = fnull)</span><br><span class="line">        fnull.<span class="built_in">close</span>()</span><br><span class="line">        <span class="keyword">if</span> <span class="built_in">result</span>:</span><br><span class="line">            <span class="literal">return</span> False</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            <span class="literal">return</span> True</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>好啦，所有的要点我们已经逐一击破，等着凯旋吧</p>
                  <h2 id="收拾战场"><a href="#收拾战场" class="headerlink" title="收拾战场"></a>收拾战场</h2>
                  <p>好了，所有的代码要点已经被我们攻破了，接下来就整理一下，让他们组合起来，变成一个应用程序吧。</p>
                  <figure class="highlight python">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">__author__ = <span class="string">'CQC'</span></span><br><span class="line"><span class="comment">#-*- coding:utf-8 -*-</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> urllib</span><br><span class="line"><span class="keyword">import</span> urllib2</span><br><span class="line"><span class="keyword">import</span> socket</span><br><span class="line"><span class="keyword">import</span> types</span><br><span class="line"><span class="keyword">import</span> time</span><br><span class="line"><span class="keyword">import</span> re</span><br><span class="line"><span class="keyword">import</span> os</span><br><span class="line"><span class="keyword">import</span> subprocess</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Login</span>:</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">#初始化</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self)</span>:</span></span><br><span class="line">        <span class="comment">#学号密码</span></span><br><span class="line">        self.username = <span class="string">'201200131012'</span></span><br><span class="line">        self.password = <span class="string">'XXXXXX'</span></span><br><span class="line">        <span class="comment">#山大无线STU的IP网段</span></span><br><span class="line">        self.ip_pre = <span class="string">'211.87'</span></span><br><span class="line">        <span class="comment">#登录时长</span></span><br><span class="line">        self.overtime = <span class="number">720</span></span><br><span class="line">        <span class="comment">#检测间隔时间，单位为秒</span></span><br><span class="line">        self.every = <span class="number">10</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">#模拟登录</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">login</span><span class="params">(self)</span>:</span></span><br><span class="line">        <span class="keyword">print</span> self.getCurrentTime(), <span class="string">u"正在尝试认证QLSC_STU无线网络"</span></span><br><span class="line">        ip = self.getIP()</span><br><span class="line">        data = &#123;</span><br><span class="line">            <span class="string">"username"</span>: self.username,</span><br><span class="line">            <span class="string">"password"</span>: self.password,</span><br><span class="line">            <span class="string">"serverType"</span>: <span class="string">""</span>,</span><br><span class="line">            <span class="string">"isSavePass"</span>: <span class="string">"on"</span>,</span><br><span class="line">            <span class="string">"Submit1"</span>: <span class="string">""</span>,</span><br><span class="line">            <span class="string">"Language"</span>: <span class="string">"Chinese"</span>,</span><br><span class="line">            <span class="string">"ClientIP"</span>: self.getIP(),</span><br><span class="line">            <span class="string">"timeoutvalue"</span>: <span class="number">45</span>,</span><br><span class="line">            <span class="string">"heartbeat"</span>: <span class="number">240</span>,</span><br><span class="line">            <span class="string">"fastwebornot"</span>: <span class="literal">False</span>,</span><br><span class="line">            <span class="string">"StartTime"</span>: self.getNowTime(),</span><br><span class="line">            <span class="comment">#持续时间，超过这个时间自动掉线，可进行设置</span></span><br><span class="line">            <span class="string">"shkOvertime"</span>: self.overtime,</span><br><span class="line">            <span class="string">"strOSName"</span>: <span class="string">""</span>,</span><br><span class="line">            <span class="string">"iAdptIndex"</span>: <span class="string">""</span>,</span><br><span class="line">            <span class="string">"strAdptName"</span>: <span class="string">""</span>,</span><br><span class="line">            <span class="string">"strAdptStdName"</span>: <span class="string">""</span>,</span><br><span class="line">            <span class="string">"strFileEncoding"</span>: <span class="string">""</span>,</span><br><span class="line">            <span class="string">"PhysAddr"</span>: <span class="string">""</span>,</span><br><span class="line">            <span class="string">"bDHCPEnabled"</span>: <span class="string">""</span>,</span><br><span class="line">            <span class="string">"strIPAddrArray"</span>: <span class="string">""</span>,</span><br><span class="line">            <span class="string">"strMaskArray"</span>: <span class="string">""</span>,</span><br><span class="line">            <span class="string">"strMask"</span>: <span class="string">""</span>,</span><br><span class="line">            <span class="string">"iDHCPDelayTime"</span>: <span class="string">""</span>,</span><br><span class="line">            <span class="string">"iDHCPTryTimes"</span>: <span class="string">""</span>,</span><br><span class="line">            <span class="string">"strOldPrivateIP"</span>: self.getIP(),</span><br><span class="line">            <span class="string">"strOldPublicIP"</span>: self.getIP(),</span><br><span class="line">            <span class="string">"strPrivateIP"</span>: self.getIP(),</span><br><span class="line">            <span class="string">"PublicIP"</span>: self.getIP(),</span><br><span class="line">            <span class="string">"iIPCONFIG"</span>:<span class="number">0</span>,</span><br><span class="line">            <span class="string">"sHttpPrefix"</span>: <span class="string">"http://192.168.8.10"</span>,</span><br><span class="line">            <span class="string">"title"</span>: <span class="string">"CAMS Portal"</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">#消息头</span></span><br><span class="line">        headers = &#123;</span><br><span class="line">            <span class="string">'User-Agent'</span> : <span class="string">'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36'</span>,</span><br><span class="line">            <span class="string">'Host'</span>: <span class="string">'192.168.8.10'</span>,</span><br><span class="line">            <span class="string">'Origin'</span>: <span class="string">'http://192.168.8.10'</span>,</span><br><span class="line">            <span class="string">'Referer'</span>: <span class="string">'http://192.168.8.10/portal/index_default.jsp?Language=Chinese'</span></span><br><span class="line">        &#125;</span><br><span class="line">        post_data = urllib.urlencode(data)</span><br><span class="line">        login_url = <span class="string">"http://192.168.8.10/portal/login.jsp?Flag=0"</span></span><br><span class="line">        request = urllib2.Request(login_url, post_data, headers)</span><br><span class="line">        response = urllib2.urlopen(request)</span><br><span class="line">        result = response.read().decode(<span class="string">'gbk'</span>)</span><br><span class="line">        self.getLoginResult(result)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">#打印登录结果</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">getLoginResult</span><span class="params">(self, result)</span>:</span></span><br><span class="line">        <span class="keyword">if</span> <span class="string">u"用户上线成功"</span> <span class="keyword">in</span> result:</span><br><span class="line">            <span class="keyword">print</span> self.getCurrentTime(),<span class="string">u"用户上线成功,在线时长为"</span>,self.overtime/<span class="number">60</span>,<span class="string">"分钟"</span></span><br><span class="line">        <span class="keyword">elif</span> <span class="string">u"您已经建立了连接"</span> <span class="keyword">in</span> result:</span><br><span class="line">            <span class="keyword">print</span> self.getCurrentTime(),<span class="string">u"您已经建立了连接,无需重复登陆"</span></span><br><span class="line">        <span class="keyword">elif</span> <span class="string">u"用户不存在"</span> <span class="keyword">in</span> result:</span><br><span class="line">            <span class="keyword">print</span> self.getCurrentTime(),<span class="string">u"用户不存在，请检查学号是否正确"</span></span><br><span class="line">        <span class="keyword">elif</span> <span class="string">u"用户密码错误"</span> <span class="keyword">in</span> result:</span><br><span class="line">            pattern = re.compile(<span class="string">'&lt;td class="tWhite"&gt;.*?2553:(.*?)&lt;/b&gt;.*?&lt;/td&gt;'</span>, re.S)</span><br><span class="line">            res = re.search(pattern, result)</span><br><span class="line">            <span class="keyword">if</span> res:</span><br><span class="line">                <span class="keyword">print</span> self.getCurrentTime(),res.group(<span class="number">1</span>),<span class="string">u"请重新修改密码"</span></span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            <span class="keyword">print</span> self.getCurrentTime(),<span class="string">u"未知错误，请检查学号密码是否正确"</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">#获取当前时间戳，13位</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">getNowTime</span><span class="params">(self)</span>:</span></span><br><span class="line">        <span class="keyword">return</span> str(int(time.time()))+<span class="string">"000"</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">#获取本机无线IP</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">getIP</span><span class="params">(self)</span>:</span></span><br><span class="line">        local_iP = socket.gethostbyname(socket.gethostname())</span><br><span class="line">        <span class="keyword">if</span> self.ip_pre <span class="keyword">in</span> str(local_iP):</span><br><span class="line">            <span class="keyword">return</span> str(local_iP)</span><br><span class="line">        ip_lists = socket.gethostbyname_ex(socket.gethostname())</span><br><span class="line"></span><br><span class="line">        <span class="keyword">for</span> ip_list <span class="keyword">in</span> ip_lists:</span><br><span class="line">            <span class="keyword">if</span> isinstance(ip_list, list):</span><br><span class="line">                <span class="keyword">for</span> i <span class="keyword">in</span> ip_list:</span><br><span class="line">                    <span class="keyword">if</span> self.ip_pre <span class="keyword">in</span> str(i):</span><br><span class="line">                        <span class="keyword">return</span> str(i)</span><br><span class="line">            <span class="keyword">elif</span> type(ip_list) <span class="keyword">is</span> types.StringType:</span><br><span class="line">                <span class="keyword">if</span> self.ip_pre <span class="keyword">in</span> ip_list:</span><br><span class="line">                    <span class="keyword">return</span> ip_list</span><br><span class="line"></span><br><span class="line">    <span class="comment">#判断当前是否可以联网</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">canConnect</span><span class="params">(self)</span>:</span></span><br><span class="line">        fnull = open(os.devnull, <span class="string">'w'</span>)</span><br><span class="line">        result = subprocess.call(<span class="string">'ping www.baidu.com'</span>, shell = <span class="literal">True</span>, stdout = fnull, stderr = fnull)</span><br><span class="line">        fnull.close()</span><br><span class="line">        <span class="keyword">if</span> result:</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">True</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">#获取当前时间</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">getCurrentTime</span><span class="params">(self)</span>:</span></span><br><span class="line">        <span class="keyword">return</span> time.strftime(<span class="string">'[%Y-%m-%d %H:%M:%S]'</span>,time.localtime(time.time()))</span><br><span class="line"></span><br><span class="line">    <span class="comment">#主函数</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">main</span><span class="params">(self)</span>:</span></span><br><span class="line">        <span class="keyword">print</span> self.getCurrentTime(), <span class="string">u"您好，欢迎使用模拟登陆系统"</span></span><br><span class="line">        <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line">            nowIP = self.getIP()</span><br><span class="line">            <span class="keyword">if</span> <span class="keyword">not</span> nowIP:</span><br><span class="line">                <span class="keyword">print</span> self.getCurrentTime(), <span class="string">u"请检查是否正常连接QLSC_STU无线网络"</span></span><br><span class="line">            <span class="keyword">else</span>:</span><br><span class="line">                <span class="keyword">print</span> self.getCurrentTime(),<span class="string">u"成功连接了QLSC_STU网络,本机IP为"</span>,nowIP</span><br><span class="line">                self.login()</span><br><span class="line">                <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line">                    can_connect = self.canConnect()</span><br><span class="line">                    <span class="keyword">if</span> <span class="keyword">not</span> can_connect:</span><br><span class="line">                        nowIP = self.getIP()</span><br><span class="line">                        <span class="keyword">if</span> <span class="keyword">not</span> nowIP:</span><br><span class="line">                            <span class="keyword">print</span> self.getCurrentTime(), <span class="string">u"当前已经掉线，请确保连接上了QLSC_STU网络"</span></span><br><span class="line">                        <span class="keyword">else</span>:</span><br><span class="line">                            <span class="keyword">print</span> self.getCurrentTime(), <span class="string">u"当前已经掉线，正在尝试重新连接"</span></span><br><span class="line">                            self.login()</span><br><span class="line">                    <span class="keyword">else</span>:</span><br><span class="line">                        <span class="keyword">print</span> self.getCurrentTime(), <span class="string">u"当前网络连接正常"</span></span><br><span class="line">                    time.sleep(self.every)</span><br><span class="line">            time.sleep(self.every)</span><br><span class="line"></span><br><span class="line">login = Login()</span><br><span class="line">login.main()</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>来，我们来运行一下，看下效果吧！ 执行</p>
                  <figure class="highlight vim">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="keyword">python</span> login.<span class="keyword">py</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>当前是可以联网的，我分别在网页上操作执行了断开，操作，程序自动检测到掉线，自动重新连接。 接下来我直接断开了QLSC_STU网络的链接，程序同样检测到QLSC_STU这个热点没有连接上，提示用户链接。 接下来我重新连接上了这个热点，由于刚才已经登录上线，且持续时间较短，网络自动恢复正常。 下面是运行结果： <a href="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/09/20150920205618.png" target="_blank" rel="noopener"><img src="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/09/20150920205618.png" alt="20150920205618"></a> 嗯，这样我们就是实现了自动掉线的检测和模拟登录。</p>
                  <h2 id="凯旋而归"><a href="#凯旋而归" class="headerlink" title="凯旋而归"></a>凯旋而归</h2>
                  <p>咿呀伊尔哟，想约妹子上自习吗？那就赶紧来试试吧！一网在手，天下我有！追男神女神都不再是梦想！ 如果有问题，欢迎留言讨论，代码肯定有不完善的地方，仅供参考。</p>
                  </p>
                </div>
              </div>
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-user"></i>
                  </span>
                  <span class="post-meta-item-text">作者</span>
                  <span><a href="/authors/崔庆才" class="author" itemprop="url" rel="index">崔庆才</a></span>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>
                  <time title="创建时间：2015-09-20 21:01:06" itemprop="dateCreated datePublished" datetime="2015-09-20T21:01:06+08:00">2015-09-20</time>
                </span>
                <span id="/2083.html" class="post-meta-item leancloud_visitors" data-flag-title="Python爬虫实战三之实现山东大学无线网络掉线自动重连" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="fa fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
                <span class="post-meta-item" title="本文字数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-file-word"></i>
                  </span>
                  <span class="post-meta-item-text">本文字数：</span>
                  <span>8.3k</span>
                </span>
                <span class="post-meta-item" title="阅读时长">
                  <span class="post-meta-item-icon">
                    <i class="far fa-clock"></i>
                  </span>
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                  <span>8 分钟</span>
                </span>
              </div>
            </article>
            <article itemscope itemtype="http://schema.org/Article" class="post-block index" lang="zh-CN">
              <link itemprop="mainEntityOfPage" href="https://cuiqingcai.com/2076.html">
              <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
                <meta itemprop="image" content="/images/avatar.png">
                <meta itemprop="name" content="崔庆才">
                <meta itemprop="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
              </span>
              <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
                <meta itemprop="name" content="静觅">
              </span>
              <header class="post-header">
                <h2 class="post-title" itemprop="name headline">
                  <a class="label"> Other <i class="label-arrow"></i>
                  </a>
                  <a href="/2076.html" class="post-title-link" itemprop="url">浅谈CSRF攻击方式</a>
                </h2>
              </header>
              <div class="post-body" itemprop="articleBody">
                <div class="thumb">
                  <img itemprop="contentUrl" class="random">
                </div>
                <div class="excerpt">
                  <p>
                  <h2 id="CSRF是什么？"><a href="#CSRF是什么？" class="headerlink" title="CSRF是什么？"></a><strong>CSRF是什么？</strong></h2>
                  <p>CSRF（Cross-site request forgery），中文名称：跨站请求伪造，也被称为：one click attack/session riding，缩写为：CSRF/XSRF。</p>
                  <h2 id="CSRF可以做什么？"><a href="#CSRF可以做什么？" class="headerlink" title="CSRF可以做什么？"></a><strong>CSRF可以做什么？</strong></h2>
                  <p>你这可以这么理解CSRF攻击：攻击者盗用了你的身份，以你的名义发送恶意请求。CSRF能够做的事情包括：以你名义发送邮件，发消息，盗取你的账号，甚至于购买商品，虚拟货币转账……造成的问题包括：个人隐私泄露以及财产安全。</p>
                  <h2 id="CSRF漏洞现状"><a href="#CSRF漏洞现状" class="headerlink" title="CSRF漏洞现状"></a><strong>CSRF漏洞现状</strong></h2>
                  <p>CSRF这种攻击方式在2000年已经被国外的安全人员提出，但在国内，直到06年才开始被关注，08年，国内外的多个大型社区和交互网站分别爆出CSRF漏洞，如：NYTimes.com（纽约时报）、Metafilter（一个大型的BLOG网站），YouTube和百度HI……而现在，互联网上的许多站点仍对此毫无防备，以至于安全业界称CSRF为“沉睡的巨人”。</p>
                  <h2 id="CSRF的原理"><a href="#CSRF的原理" class="headerlink" title="CSRF的原理"></a><strong>CSRF的原理</strong></h2>
                  <p>下图简单阐述了CSRF攻击的思想： <img src="http://pic002.cnblogs.com/img/hyddd/200904/2009040916453171.jpg" alt=""> 从上图可以看出，要完成一次CSRF攻击，受害者必须依次完成两个步骤：</p>
                  <blockquote>
                    <p>　　1.登录受信任网站A，并在本地生成Cookie。 2.在不登出A的情况下，访问危险网站B。</p>
                  </blockquote>
                  <p>看到这里，你也许会说：“如果我不满足以上两个条件中的一个，我就不会受到CSRF的攻击”。是的，确实如此，但你不能保证以下情况不会发生：</p>
                  <blockquote>
                    <p>　　1.你不能保证你登录了一个网站后，不再打开一个tab页面并访问另外的网站。 2.你不能保证你关闭浏览器了后，你本地的Cookie立刻过期，你上次的会话已经结束。（事实上，关闭浏览器不能结束一个会话，但大多数人都会错误的认为关闭浏览器就等于退出登录/结束会话了……） 3.上图中所谓的攻击网站，可能是一个存在其他漏洞的可信任的经常被人访问的网站。</p>
                  </blockquote>
                  <p>上面大概地讲了一下CSRF攻击的思想，下面我将用几个例子详细说说具体的CSRF攻击，这里我以一个银行转账的操作作为例子（仅仅是例子，真实的银行网站没这么傻:&gt;）</p>
                  <h3 id="示例1："><a href="#示例1：" class="headerlink" title="示例1："></a><strong>示例1：</strong></h3>
                  <p>银行网站A，它以GET请求来完成银行转账的操作，如：<a href="http://www.mybank.com/Transfer.php?toBankId=11&amp;money=1000" target="_blank" rel="noopener">http://www.mybank.com/Transfer.php?toBankId=11&amp;money=1000</a> 危险网站B，它里面有一段HTML的代码如下：</p>
                  <figure class="highlight xml">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="tag">&lt;<span class="name">img</span> <span class="attr">src</span>=<span class="string">http://www.mybank.com/Transfer.php?toBankId</span>=<span class="string">11&amp;money</span>=<span class="string">1000</span>&gt;</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>首先，你登录了银行网站A，然后访问危险网站B，噢，这时你会发现你的银行账户少了1000块…… 为什么会这样呢？原因是银行网站A违反了HTTP规范，使用GET请求更新资源。在访问危险网站B的之前，你已经登录了银行网站A，而B中的<img>以GET的方式请求第三方资源（这里的第三方就是指银行网站了，原本这是一个合法的请求，但这里被不法分子利用了），所以你的浏览器会带上你的银行网站A的Cookie发出Get请求，去获取资源“<a href="http://www.mybank.com/Transfer.php?toBankId=11&amp;money=1000”，结果银行网站服务器收到请求后，认为这是一个更新资源操作（转账操作），所以就立刻进行转账操作" target="_blank" rel="noopener">http://www.mybank.com/Transfer.php?toBankId=11&amp;money=1000”，结果银行网站服务器收到请求后，认为这是一个更新资源操作（转账操作），所以就立刻进行转账操作</a>……</p>
                  <h3 id="示例2："><a href="#示例2：" class="headerlink" title="　　示例2："></a>　　<strong>示例2：</strong></h3>
                  <p>为了杜绝上面的问题，银行决定改用POST请求完成转账操作。 银行网站A的WEB表单如下：</p>
                  <figure class="highlight xml">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">　　<span class="tag">&lt;<span class="name">form</span> <span class="attr">action</span>=<span class="string">"Transfer.php"</span> <span class="attr">method</span>=<span class="string">"POST"</span>&gt;</span></span><br><span class="line">　　　　<span class="tag">&lt;<span class="name">p</span>&gt;</span>ToBankId: <span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">"text"</span> <span class="attr">name</span>=<span class="string">"toBankId"</span> /&gt;</span><span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br><span class="line">　　　　<span class="tag">&lt;<span class="name">p</span>&gt;</span>Money: <span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">"text"</span> <span class="attr">name</span>=<span class="string">"money"</span> /&gt;</span><span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br><span class="line">　　　　<span class="tag">&lt;<span class="name">p</span>&gt;</span><span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">"submit"</span> <span class="attr">value</span>=<span class="string">"Transfer"</span> /&gt;</span><span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br><span class="line">　　<span class="tag">&lt;/<span class="name">form</span>&gt;</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>后台处理页面Transfer.php如下：</p>
                  <figure class="highlight xml">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">　　<span class="php"><span class="meta">&lt;?php</span></span></span><br><span class="line"><span class="php">　　　　session_start();</span></span><br><span class="line"><span class="php">　　　　<span class="keyword">if</span> (<span class="keyword">isset</span>($_REQUEST[<span class="string">'toBankId'</span>] &amp;&amp;　<span class="keyword">isset</span>($_REQUEST[<span class="string">'money'</span>]))</span></span><br><span class="line"><span class="php">　　　　&#123;</span></span><br><span class="line"><span class="php">　　　　    buy_stocks($_REQUEST[<span class="string">'toBankId'</span>],　$_REQUEST[<span class="string">'money'</span>]);</span></span><br><span class="line"><span class="php">　　　　&#125;</span></span><br><span class="line"><span class="php">　　<span class="meta">?&gt;</span></span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>危险网站B，仍然只是包含那句HTML代码：</p>
                  <figure class="highlight xml">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="tag">&lt;<span class="name">img</span> <span class="attr">src</span>=<span class="string">http://www.mybank.com/Transfer.php?toBankId</span>=<span class="string">11&amp;money</span>=<span class="string">1000</span>&gt;</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>和示例1中的操作一样，你首先登录了银行网站A，然后访问危险网站B，结果…..和示例1一样，你再次没了1000块～T_T，这次事故的原因是：银行后台使用了$_REQUEST去获取请求的数据，而$_REQUEST既可以获取GET请求的数据，也可以获取POST请求的数据，这就造成了在后台处理程序无法区分这到底是GET请求的数据还是POST请求的数据。在PHP中，可以使用$_GET和$_POST分别获取GET请求和POST请求的数据。在JAVA中，用于获取请求数据request一样存在不能区分GET请求数据和POST数据的问题。</p>
                  <h3 id="示例3："><a href="#示例3：" class="headerlink" title="　　示例3："></a>　　<strong>示例3：</strong></h3>
                  <p>经过前面2个惨痛的教训，银行决定把获取请求数据的方法也改了，改用$_POST，只获取POST请求的数据，后台处理页面Transfer.php代码如下：</p>
                  <figure class="highlight xml">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">　　<span class="php"><span class="meta">&lt;?php</span></span></span><br><span class="line"><span class="php">　　　　session_start();</span></span><br><span class="line"><span class="php">　　　　<span class="keyword">if</span> (<span class="keyword">isset</span>($_POST[<span class="string">'toBankId'</span>] &amp;&amp;　<span class="keyword">isset</span>($_POST[<span class="string">'money'</span>]))</span></span><br><span class="line"><span class="php">　　　　&#123;</span></span><br><span class="line"><span class="php">　　　　    buy_stocks($_POST[<span class="string">'toBankId'</span>],　$_POST[<span class="string">'money'</span>]);</span></span><br><span class="line"><span class="php">　　　　&#125;</span></span><br><span class="line"><span class="php">　　<span class="meta">?&gt;</span></span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>然而，危险网站B与时俱进，它改了一下代码：</p>
                  <figure class="highlight xml">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="tag">&lt;<span class="name">html</span>&gt;</span></span><br><span class="line">　　<span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">　　　　<span class="tag">&lt;<span class="name">script</span> <span class="attr">type</span>=<span class="string">"text/javascript"</span>&gt;</span></span><br><span class="line"><span class="actionscript">　　　　　　<span class="function"><span class="keyword">function</span> <span class="title">steal</span><span class="params">()</span></span></span></span><br><span class="line">　　　　　　&#123;</span><br><span class="line"><span class="javascript">          　　　　 iframe = <span class="built_in">document</span>.frames[<span class="string">"steal"</span>];</span></span><br><span class="line"><span class="actionscript">　　     　　      iframe.document.Submit(<span class="string">"transfer"</span>);</span></span><br><span class="line">　　　　　　&#125;</span><br><span class="line">　　　　<span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line">　　<span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line"></span><br><span class="line">　　<span class="tag">&lt;<span class="name">body</span> <span class="attr">onload</span>=<span class="string">"steal()"</span>&gt;</span></span><br><span class="line">　　　　<span class="tag">&lt;<span class="name">iframe</span> <span class="attr">name</span>=<span class="string">"steal"</span> <span class="attr">display</span>=<span class="string">"none"</span>&gt;</span></span><br><span class="line">　　　　　　<span class="tag">&lt;<span class="name">form</span> <span class="attr">method</span>=<span class="string">"POST"</span> <span class="attr">name</span>=<span class="string">"transfer"</span>　<span class="attr">action</span>=<span class="string">"http://www.myBank.com/Transfer.php"</span>&gt;</span></span><br><span class="line">　　　　　　　　<span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">"hidden"</span> <span class="attr">name</span>=<span class="string">"toBankId"</span> <span class="attr">value</span>=<span class="string">"11"</span>&gt;</span></span><br><span class="line">　　　　　　　　<span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">"hidden"</span> <span class="attr">name</span>=<span class="string">"money"</span> <span class="attr">value</span>=<span class="string">"1000"</span>&gt;</span></span><br><span class="line">　　　　　　<span class="tag">&lt;/<span class="name">form</span>&gt;</span></span><br><span class="line">　　　　<span class="tag">&lt;/<span class="name">iframe</span>&gt;</span></span><br><span class="line">　　<span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>如果用户仍是继续上面的操作，很不幸，结果将会是再次不见1000块……因为这里危险网站B暗地里发送了POST请求到银行! 总结一下上面3个例子，CSRF主要的攻击模式基本上是以上的3种，其中以第1,2种最为严重，因为触发条件很简单，一个<img>就可以了，而第3种比较麻烦，需要使用JavaScript，所以使用的机会会比前面的少很多，但无论是哪种情况，只要触发了CSRF攻击，后果都有可能很严重。 理解上面的3种攻击模式，其实可以看出，CSRF攻击是源于WEB的隐式身份验证机制！WEB的身份验证机制虽然可以保证一个请求是来自于某个用户的浏览器，但却无法保证该请求是用户批准发送的！</p>
                  <h2 id="CSRF的防御"><a href="#CSRF的防御" class="headerlink" title="CSRF的防御"></a><strong>CSRF的防御</strong></h2>
                  <p>我总结了一下看到的资料，CSRF的防御可以从服务端和客户端两方面着手，防御效果是从服务端着手效果比较好，现在一般的CSRF防御也都在服务端进行。</p>
                  <h3 id="1-服务端进行CSRF防御"><a href="#1-服务端进行CSRF防御" class="headerlink" title="　　1.服务端进行CSRF防御"></a>　　<strong>1.服务端进行CSRF防御</strong></h3>
                  <p>服务端的CSRF方式方法很多样，但总的思想都是一致的，就是在客户端页面增加伪随机数。 (1).Cookie Hashing(所有表单都包含同一个伪随机值)： 这可能是最简单的解决方案了，因为攻击者不能获得第三方的Cookie(理论上)，所以表单中的数据也就构造失败了:&gt;</p>
                  <figure class="highlight xml">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">　　<span class="php"><span class="meta">&lt;?php</span></span></span><br><span class="line"><span class="php">　　　　<span class="comment">//构造加密的Cookie信息</span></span></span><br><span class="line"><span class="php">　　　　$value = “DefenseSCRF”;</span></span><br><span class="line"><span class="php">　　　　setcookie(”cookie”, $value, time()+<span class="number">3600</span>);</span></span><br><span class="line"><span class="php">　　<span class="meta">?&gt;</span></span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>在表单里增加Hash值，以认证这确实是用户发送的请求。</p>
                  <figure class="highlight django">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="xml">　　<span class="php"><span class="meta">&lt;?php</span></span></span></span><br><span class="line"><span class="xml">　　　　$hash = md5($_COOKIE['cookie']);</span></span><br><span class="line"><span class="xml">　　?&gt;</span></span><br><span class="line"><span class="xml">　　<span class="tag">&lt;<span class="name">form</span> <span class="attr">method</span>=<span class="string">”POST”</span> <span class="attr">action</span>=<span class="string">”transfer.php”</span>&gt;</span></span></span><br><span class="line"><span class="xml">　　　　<span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">”text”</span> <span class="attr">name</span>=<span class="string">”toBankId”</span>&gt;</span></span></span><br><span class="line"><span class="xml">　　　　<span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">”text”</span> <span class="attr">name</span>=<span class="string">”money”</span>&gt;</span></span></span><br><span class="line"><span class="xml">　　　　<span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">”hidden”</span> <span class="attr">name</span>=<span class="string">”hash”</span> <span class="attr">value</span>=<span class="string">”</span>&lt;?=<span class="string">$hash;?</span>&gt;</span>”&gt;</span></span><br><span class="line"><span class="xml">　　　　<span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">”submit”</span> <span class="attr">name</span>=<span class="string">”submit”</span> <span class="attr">value</span>=<span class="string">”Submit”</span>&gt;</span></span></span><br><span class="line"><span class="xml">　　<span class="tag">&lt;/<span class="name">form</span>&gt;</span></span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>然后在服务器端进行Hash值验证</p>
                  <figure class="highlight xml">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">      <span class="php"><span class="meta">&lt;?php</span></span></span><br><span class="line"><span class="php">　　      <span class="keyword">if</span>(<span class="keyword">isset</span>($_POST[<span class="string">'check'</span>])) &#123;</span></span><br><span class="line"><span class="php">     　　      $hash = md5($_COOKIE[<span class="string">'cookie'</span>]);</span></span><br><span class="line"><span class="php">          　　 <span class="keyword">if</span>($_POST[<span class="string">'check'</span>] == $hash) &#123;</span></span><br><span class="line"><span class="php">               　　 doJob();</span></span><br><span class="line"><span class="php">　　           &#125; <span class="keyword">else</span> &#123;</span></span><br><span class="line"><span class="php">　　　　　　　　<span class="comment">//...</span></span></span><br><span class="line"><span class="php">          　　 &#125;</span></span><br><span class="line"><span class="php">　　      &#125; <span class="keyword">else</span> &#123;</span></span><br><span class="line"><span class="php">　　　　　　<span class="comment">//...</span></span></span><br><span class="line"><span class="php">　　      &#125;</span></span><br><span class="line"><span class="php">      <span class="meta">?&gt;</span></span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>这个方法个人觉得已经可以杜绝99%的CSRF攻击了，那还有1%呢….由于用户的Cookie很容易由于网站的XSS漏洞而被盗取，这就另外的1%。一般的攻击者看到有需要算Hash值，基本都会放弃了，某些除外，所以如果需要100%的杜绝，这个不是最好的方法。</p>
                  <h3 id="2-验证码"><a href="#2-验证码" class="headerlink" title="2.验证码"></a>2.验证码</h3>
                  <p>这个方案的思路是：每次的用户提交都需要用户在表单中填写一个图片上的随机字符串，厄….这个方案可以完全解决CSRF，但个人觉得在易用性方面似乎不是太好，还有听闻是验证码图片的使用涉及了一个被称为MHTML的Bug，可能在某些版本的微软IE中受影响。</p>
                  <h2 id="原文链接"><a href="#原文链接" class="headerlink" title="原文链接"></a>原文链接</h2>
                  <p>在网上发现这篇文章说得很明了，转载啦，非常感谢原作者的辛苦付出。 <a href="http://www.cnblogs.com/hyddd/archive/2009/04/09/1432744.html" target="_blank" rel="noopener">原文出处</a></p>
                  </p>
                </div>
              </div>
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-user"></i>
                  </span>
                  <span class="post-meta-item-text">作者</span>
                  <span><a href="/authors/崔庆才" class="author" itemprop="url" rel="index">崔庆才</a></span>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>
                  <time title="创建时间：2015-09-17 23:08:41" itemprop="dateCreated datePublished" datetime="2015-09-17T23:08:41+08:00">2015-09-17</time>
                </span>
                <span id="/2076.html" class="post-meta-item leancloud_visitors" data-flag-title="浅谈CSRF攻击方式" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="fa fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
                <span class="post-meta-item" title="本文字数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-file-word"></i>
                  </span>
                  <span class="post-meta-item-text">本文字数：</span>
                  <span>4.4k</span>
                </span>
                <span class="post-meta-item" title="阅读时长">
                  <span class="post-meta-item-icon">
                    <i class="far fa-clock"></i>
                  </span>
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                  <span>4 分钟</span>
                </span>
              </div>
            </article>
            <article itemscope itemtype="http://schema.org/Article" class="post-block index" lang="zh-CN">
              <link itemprop="mainEntityOfPage" href="https://cuiqingcai.com/2057.html">
              <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
                <meta itemprop="image" content="/images/avatar.png">
                <meta itemprop="name" content="崔庆才">
                <meta itemprop="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
              </span>
              <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
                <meta itemprop="name" content="静觅">
              </span>
              <header class="post-header">
                <h2 class="post-title" itemprop="name headline">
                  <a class="label"> Other <i class="label-arrow"></i>
                  </a>
                  <a href="/2057.html" class="post-title-link" itemprop="url">怎样把你的SAE利用起来</a>
                </h2>
              </header>
              <div class="post-body" itemprop="articleBody">
                <div class="thumb">
                  <img itemprop="contentUrl" class="random">
                </div>
                <div class="excerpt">
                  <p>
                  <h2 id="综述"><a href="#综述" class="headerlink" title="综述"></a>综述</h2>
                  <p>博主没事就喜欢瞎倒腾，今天登录自己的SAE一看，很久之前挂的几个应用早已杳无人烟，才消耗几个云豆，真是觉得太浪费了。所以博主就瞎倒腾一下，准备好好利用起自己的云豆，尽可能地为我提供服务。 好了，废话不多说，让我们开始动起来！</p>
                  <h2 id="新建应用"><a href="#新建应用" class="headerlink" title="新建应用"></a>新建应用</h2>
                  <p>既然想利用好里面的服务，那么我们就需要新建一个专属应用，取个专属名称，那么我名字叫崔庆才，那就叫cuiqingcai好了，幸运的是，并没有同名应用，可以使用，不错不错。 <a href="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/09/20150912153748.png" target="_blank" rel="noopener"><img src="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/09/20150912153748.png" alt="20150912153748"></a></p>
                  <h2 id="数据库"><a href="#数据库" class="headerlink" title="数据库"></a>数据库</h2>
                  <p>SAE上最近出了一种独享数据库，不像之前的数据库一样每建一个应用自动生成一个数据库，这个数据库就像平常我们用到的phpMyAdmin一样一样的。可以新建好多个数据库，可以远程连接，可以登录网页设置。 有了这个，如果你没有VPS，也不需要去买个RDS来用啦！ <a href="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/09/20150912152842.png" target="_blank" rel="noopener"><img src="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/09/20150912152842.png" alt="20150912152842"></a> 首先建立好应用之后，到应用管理界面去，点击你的MySQL，然后就会让你选择是哪一种数据库，右边的独享型MySQL是SAE新出的，功能也非常强，可以建立数据库，可以建用户，授权数据库，监控数据等等。 <a href="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/09/20150912153909.png" target="_blank" rel="noopener"><img src="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/09/20150912153909-1024x538.png" alt="20150912153909"></a> 点击独享型MySQL，创建属于自己的数据库吧。创建好了，建立自己的账户，登进来，一切都是那么轻松加愉快，以后有什么需要数据库，扔到这里就好了。 <a href="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/09/20150912154219.png" target="_blank" rel="noopener"><img src="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/09/20150912154219-1024x432.png" alt="20150912154219"></a> 好，相信这个一定非常简单，小伙伴们快试一下吧！</p>
                  <h2 id="Storage"><a href="#Storage" class="headerlink" title="Storage"></a>Storage</h2>
                  <p>新浪云中提供了SCS，也是一个云存储服务，但是费用太坑了，而且不是消耗云豆的，然而应用中的Storage是使用云豆的，如果不是什么私密存储的话，还是可以利用一下的。 在这里我想让它发挥SCS的作用并绑定到我的域名上，这样通过scs.cuiqingcai.com便可以访问了。 我们新建一个Storage Domain <a href="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/09/20150912155842.png" target="_blank" rel="noopener"><img src="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/09/20150912155842-1024x368.png" alt="20150912155842"></a> 上传一张图片进去，比如1.jpg，上传后访问一下 <a href="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/09/20150912160138.png" target="_blank" rel="noopener"><img src="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/09/20150912160138.png" alt="20150912160138"></a> 恩，轻松加愉快！接下来，我发现这个域名简直太难记了，我要换成自己的域名，比如 scs.cuiqingcai.com 这样，图片就可以通过 scs.cuiqingcai.com/1.jpg 来访问了。那么怎么配置呢？</p>
                  <h3 id="1-绑定域名"><a href="#1-绑定域名" class="headerlink" title="1.绑定域名"></a>1.绑定域名</h3>
                  <p>到应用首页里面，点击域名绑定，SAE会告诉你两条要解析的内容，自己设置一下 <a href="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/09/20150912160935.png" target="_blank" rel="noopener"><img src="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/09/20150912160935.png" alt="20150912160935"></a> 接下来我们需要配置一下代码</p>
                  <h3 id="2-修改config-yaml"><a href="#2-修改config-yaml" class="headerlink" title="2.修改config.yaml"></a>2.修改config.yaml</h3>
                  <p>需要在代码管理中，更改一下config.yaml文件，让它做一个跳转。 比如我的代码中 config.yaml 文件就更改为</p>
                  <figure class="highlight groovy">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="string">name:</span> cuiqingcai</span><br><span class="line"><span class="string">version:</span> <span class="number">1</span></span><br><span class="line"><span class="string">handle:</span></span><br><span class="line">	- <span class="string">rewrite:</span> <span class="keyword">if</span> (path ~ <span class="string">"/(.*)"</span>) goto <span class="string">"http://cuiqingcai-scs.stor.sinaapp.com/$1"</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>其实就是加了一条reweite语句，把所有的路径定位到新地址的新路径中。 接下来，我访问一下 scs.cuiqingcai.com/1.jpg，嗯，图片出来了！这样，又一个免费的CDN建好了！ <a href="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/09/20150912161437.png" target="_blank" rel="noopener"><img src="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/09/20150912161437.png" alt="20150912161437"></a> 嗯，如果有什么图片需要存放，它会是你的一个非常好的选择！ 上传的话，SAE提供了上传的客户端，大家可以自行下载尝试。 之后博主将研究一下怎样配置上传的接口，这样我们就可以通过程序来上传了，我也很期待呢！</p>
                  <h2 id="结语"><a href="#结语" class="headerlink" title="结语"></a>结语</h2>
                  <p>以上是博主瞎倒腾的，可以为自己提供一些方便，大家尝试下吧，如有问题，欢迎留言交流！</p>
                  </p>
                </div>
              </div>
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-user"></i>
                  </span>
                  <span class="post-meta-item-text">作者</span>
                  <span><a href="/authors/崔庆才" class="author" itemprop="url" rel="index">崔庆才</a></span>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>
                  <time title="创建时间：2015-09-12 16:17:41" itemprop="dateCreated datePublished" datetime="2015-09-12T16:17:41+08:00">2015-09-12</time>
                </span>
                <span id="/2057.html" class="post-meta-item leancloud_visitors" data-flag-title="怎样把你的SAE利用起来" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="fa fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
                <span class="post-meta-item" title="本文字数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-file-word"></i>
                  </span>
                  <span class="post-meta-item-text">本文字数：</span>
                  <span>1.3k</span>
                </span>
                <span class="post-meta-item" title="阅读时长">
                  <span class="post-meta-item-icon">
                    <i class="far fa-clock"></i>
                  </span>
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                  <span>1 分钟</span>
                </span>
              </div>
            </article>
            <article itemscope itemtype="http://schema.org/Article" class="post-block index" lang="zh-CN">
              <link itemprop="mainEntityOfPage" href="https://cuiqingcai.com/2036.html">
              <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
                <meta itemprop="image" content="/images/avatar.png">
                <meta itemprop="name" content="崔庆才">
                <meta itemprop="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
              </span>
              <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
                <meta itemprop="name" content="静觅">
              </span>
              <header class="post-header">
                <h2 class="post-title" itemprop="name headline">
                  <a class="label"> Linux <i class="label-arrow"></i>
                  </a>
                  <a href="/2036.html" class="post-title-link" itemprop="url">Ubuntu Linux配置Nginx+MySQL+PHP+phpMyAdmin详细步骤</a>
                </h2>
              </header>
              <div class="post-body" itemprop="articleBody">
                <div class="thumb">
                  <img itemprop="contentUrl" class="random">
                </div>
                <div class="excerpt">
                  <p>
                  <p>博主之前一直用的是apache，随着网站负荷量增高，感觉apache稍微有点力不从心了。随着nginx越来越流行，而且其功能强大，博主准备采用nginx作为自己的服务器啦。 每当到了环境配置的时候，博主便会去网上各种搜集资料，然而感觉他们讲的都条理不一，有的地方并不符合自己的配置习惯，所以博主习惯自己配置的同时把配置过程总结一下，方便自己，也方便大家。 好，接下来我们就开始我们的环境配置之旅吧。</p>
                  <h2 id="Nginx"><a href="#Nginx" class="headerlink" title="Nginx"></a>Nginx</h2>
                  <h3 id="1-更新源"><a href="#1-更新源" class="headerlink" title="1.更新源"></a>1.更新源</h3>
                  <figure class="highlight pgsql">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">sudo apt-<span class="keyword">get</span> <span class="keyword">update</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <h3 id="2-安装nginx"><a href="#2-安装nginx" class="headerlink" title="2.安装nginx"></a>2.安装nginx</h3>
                  <figure class="highlight routeros">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">sudo apt-<span class="builtin-name">get</span> install nginx</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <h3 id="3-检查是否安装成功"><a href="#3-检查是否安装成功" class="headerlink" title="3.检查是否安装成功"></a>3.检查是否安装成功</h3>
                  <p>输入localhost或者远程地址，若出现Welcome To Nginx则证明安装成功。 <a href="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/09/20150911144903.png" target="_blank" rel="noopener"><img src="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/09/20150911144903.png" alt="20150911144903"></a> 如果没有看到，可以运行</p>
                  <figure class="highlight nginx">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="attribute">sudo</span> killall apache2</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>杀掉apache进程，因为可能80端口被占用了。</p>
                  <h3 id="4-更改运行目录"><a href="#4-更改运行目录" class="headerlink" title="4.更改运行目录"></a>4.更改运行目录</h3>
                  <p>默认的nginx目录是/usr/share/nginx/html，我们将其修改为/var/www，当然可以根据个人习惯灵活更改。 修改/etc/nginx/sites-available/default文件</p>
                  <figure class="highlight awk">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">root <span class="regexp">/usr/</span>share<span class="regexp">/nginx/</span>html;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>更改为</p>
                  <figure class="highlight actionscript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">root /<span class="keyword">var</span>/www</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>再将</p>
                  <figure class="highlight n1ql">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="keyword">index</span> <span class="keyword">index</span>.html <span class="keyword">index</span>.htm;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>更改为</p>
                  <figure class="highlight n1ql">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="keyword">index</span> <span class="keyword">index</span>.html <span class="keyword">index</span>.php <span class="keyword">index</span>.htm;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>重启nginx</p>
                  <figure class="highlight routeros">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">sudo<span class="built_in"> service </span>nginx restart</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>我们在/var/www目录下新建index.html文件，写入一些测试文字。 重新访问localhost或者远程地址，可以看到刚才设置的index.html文件中的内容，说明目录已经更改成功了。</p>
                  <h2 id="PHP"><a href="#PHP" class="headerlink" title="PHP"></a>PHP</h2>
                  <p>安装PHP以及相关扩展。</p>
                  <figure class="highlight smali">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">sudo apt-get install php5 php5-cgi php5-mysql php5-curl php5-gd php5-idn php-pear php5-imagick php5-imap php5-mcrypt php5-memcache php5-mhash php5-ming php5-pspell php5-recode php5-snmp php5-tidy php5-xmlrpc php5-sqlite php5-xsl</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>执行上述指令即可。 此时有的小伙伴想要测试运行PHP文件了，然而很悲剧地告诉你是不可以的，因为你还没有配置fastcgi，继续往下看。</p>
                  <h2 id="MySQL"><a href="#MySQL" class="headerlink" title="MySQL"></a>MySQL</h2>
                  <p>执行如下命令，安装MySQL服务端和客户端。</p>
                  <figure class="highlight sql">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">sudo apt-get <span class="keyword">install</span> mysql-<span class="keyword">server</span> mysql-<span class="keyword">client</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>在安装时可能提示你输入root用户的密码，设置即可。</p>
                  <h2 id="phpMyAdmin"><a href="#phpMyAdmin" class="headerlink" title="phpMyAdmin"></a>phpMyAdmin</h2>
                  <p>执行如下命令，安装phpMyAdmin。</p>
                  <figure class="highlight routeros">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">sudo apt-<span class="builtin-name">get</span> install phpmyadmin</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>创建软连接</p>
                  <figure class="highlight awk">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">sudo ln -s <span class="regexp">/usr/</span>share<span class="regexp">/phpmyadmin/</span> <span class="regexp">/var/</span>www<span class="regexp">/phpmyadmin</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>我们将创建一个根目录为/var/www，链接名为phpmyadmin的文件，指向/usr/share/phpmyadmin</p>
                  <h2 id="spawn-fcgi"><a href="#spawn-fcgi" class="headerlink" title="spawn-fcgi"></a>spawn-fcgi</h2>
                  <h3 id="1-安装fastcgi"><a href="#1-安装fastcgi" class="headerlink" title="1.安装fastcgi"></a>1.安装fastcgi</h3>
                  <figure class="highlight routeros">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">sudo apt-<span class="builtin-name">get</span> install spawn-fcgi</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <h3 id="2-配置fastcgi"><a href="#2-配置fastcgi" class="headerlink" title="2.配置fastcgi"></a>2.配置fastcgi</h3>
                  <p>修改 /etc/nginx/fastcgi_params文件，增加下面一行</p>
                  <figure class="highlight nginx">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="attribute">fastcgi_param</span> SCRIPT_FILENAME <span class="variable">$document_root</span><span class="variable">$fastcgi_script_name</span>;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>修改/etc/php5/cgi/php.ini文件，将下面一行取消注释</p>
                  <figure class="highlight ini">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="attr">cgi.fix_pathinfo</span>=<span class="number">1</span><span class="comment">;</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>这样php-cgi方能正常使用SCRIPT_FILENAME这个变量 修改/etc/nginx/sites-available/default文件，我们之前修改的目录地址是/var/www，将</p>
                  <figure class="highlight vala">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="meta">#location ~ \.php$ &#123;</span></span><br><span class="line"><span class="meta">#	fastcgi_split_path_info ^(.+\.php)(/.+)$;</span></span><br><span class="line"><span class="meta">#	# NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini</span></span><br><span class="line"><span class="meta">#</span></span><br><span class="line"><span class="meta">#	# With php5-cgi alone:</span></span><br><span class="line"><span class="meta">#	fastcgi_pass 127.0.0.1:9000;</span></span><br><span class="line"><span class="meta">#	# With php5-fpm:</span></span><br><span class="line"><span class="meta">#	fastcgi_pass unix:/var/run/php5-fpm.sock;</span></span><br><span class="line"><span class="meta">#	fastcgi_index index.php;</span></span><br><span class="line"><span class="meta">#	include fastcgi_params;</span></span><br><span class="line"><span class="meta">#&#125;</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>修改为</p>
                  <figure class="highlight nginx">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="attribute">location</span> <span class="regexp">~ \.php$</span> &#123;</span><br><span class="line"><span class="comment">#	fastcgi_split_path_info ^(.+\.php)(/.+)$;</span></span><br><span class="line"><span class="comment">#	# <span class="doctag">NOTE:</span> You should have "cgi.fix_pathinfo = 0;" in php.ini</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment">#	# With php5-cgi alone:</span></span><br><span class="line">	<span class="attribute">fastcgi_pass</span> <span class="number">127.0.0.1:9000</span>;</span><br><span class="line"><span class="comment">#	# With php5-fpm:</span></span><br><span class="line"><span class="comment">#	fastcgi_pass unix:/var/run/php5-fpm.sock;</span></span><br><span class="line">	<span class="attribute">fastcgi_index</span> index.php;</span><br><span class="line">	<span class="attribute">fastcgi_param</span> SCRIPT_FILENAME /var/www<span class="variable">$fastcgi_script_name</span>;</span><br><span class="line">	<span class="attribute">include</span> fastcgi_params;</span><br><span class="line">&#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <h3 id="3-开启fastcgi进程"><a href="#3-开启fastcgi进程" class="headerlink" title="3.开启fastcgi进程"></a>3.开启fastcgi进程</h3>
                  <figure class="highlight angelscript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">sudo /usr/bin/spawn-fcgi -a <span class="number">127.0</span><span class="number">.0</span><span class="number">.1</span> -p <span class="number">9000</span> -C <span class="number">5</span> -u www-data -g www-data -f /usr/bin/php5-cgi -P /var/run/fastcgi-php.pid</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>参数含义如下</p>
                  <blockquote>
                    <p>　　<em> -f 指定调用FastCGI的进程的执行程序位置，根据系统上所装的PHP的情况具体设置 </em> -a 绑定到地址addr <em> -p 绑定到端口port </em> -s 绑定到unix socket的路径path <em> -C 指定产生的FastCGI的进程数，默认为5（仅用于PHP） </em> -P指定产生的进程的PID文件路径 * -u和-g FastCGI使用什么身份（-u 用户 -g 用户组）运行，Ubuntu下可以使用www-data,其他的根据情况配置，如nobody、apache等现在可以在web根目录下放个探针或php文件测试一下了</p>
                  </blockquote>
                  <p>运行结果类似如下</p>
                  <figure class="highlight groovy">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">spawn-<span class="string">fcgi:</span> child spawned <span class="string">successfully:</span> <span class="string">PID:</span> <span class="number">11775</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <h3 id="4-设置开机启动fastcgi"><a href="#4-设置开机启动fastcgi" class="headerlink" title="4.设置开机启动fastcgi"></a>4.设置开机启动fastcgi</h3>
                  <p>修改/etc/rc.local文件，添加下面一行</p>
                  <figure class="highlight angelscript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">/usr/bin/spawn-fcgi -a <span class="number">127.0</span><span class="number">.0</span><span class="number">.1</span> -p <span class="number">9000</span> -C <span class="number">5</span> -u www-data -g www-data -f /usr/bin/php5-cgi -P /var/run/fastcgi-php.pid</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>修改完之后，重启nginx</p>
                  <figure class="highlight routeros">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">sudo<span class="built_in"> service </span>nginx restart</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>我们可以在/var/www目录下新建index.php文件测试运行，发现已经可以运行PHP文件了。</p>
                  <h2 id="测试运行"><a href="#测试运行" class="headerlink" title="测试运行"></a>测试运行</h2>
                  <p>所有配置已经完毕，现在我们输入localhost和localhost/phpmyadmin便可以轻松加愉快地访问了。 如有问题，欢迎交流。</p>
                  </p>
                </div>
              </div>
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-user"></i>
                  </span>
                  <span class="post-meta-item-text">作者</span>
                  <span><a href="/authors/崔庆才" class="author" itemprop="url" rel="index">崔庆才</a></span>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>
                  <time title="创建时间：2015-09-11 15:23:36" itemprop="dateCreated datePublished" datetime="2015-09-11T15:23:36+08:00">2015-09-11</time>
                </span>
                <span id="/2036.html" class="post-meta-item leancloud_visitors" data-flag-title="Ubuntu Linux配置Nginx+MySQL+PHP+phpMyAdmin详细步骤" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="fa fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
                <span class="post-meta-item" title="本文字数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-file-word"></i>
                  </span>
                  <span class="post-meta-item-text">本文字数：</span>
                  <span>2.9k</span>
                </span>
                <span class="post-meta-item" title="阅读时长">
                  <span class="post-meta-item-icon">
                    <i class="far fa-clock"></i>
                  </span>
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                  <span>3 分钟</span>
                </span>
              </div>
            </article>
            <article itemscope itemtype="http://schema.org/Article" class="post-block index" lang="zh-CN">
              <link itemprop="mainEntityOfPage" href="https://cuiqingcai.com/1972.html">
              <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
                <meta itemprop="image" content="/images/avatar.png">
                <meta itemprop="name" content="崔庆才">
                <meta itemprop="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
              </span>
              <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
                <meta itemprop="name" content="静觅">
              </span>
              <header class="post-header">
                <h2 class="post-title" itemprop="name headline">
                  <a class="label"> Python <i class="label-arrow"></i>
                  </a>
                  <a href="/1972.html" class="post-title-link" itemprop="url">Python爬虫实战六之抓取爱问知识人问题并保存至数据库</a>
                </h2>
              </header>
              <div class="post-body" itemprop="articleBody">
                <div class="thumb">
                  <img itemprop="contentUrl" class="random">
                </div>
                <div class="excerpt">
                  <p>
                  <p>大家好，本次为大家带来的是抓取爱问知识人的问题并将问题和答案保存到数据库的方法，涉及的内容包括：</p>
                  <ul>
                    <li>Urllib的用法及异常处理</li>
                    <li>Beautiful Soup的简单应用</li>
                    <li>MySQLdb的基础用法</li>
                    <li>正则表达式的简单应用</li>
                  </ul>
                  <h2 id="环境配置"><a href="#环境配置" class="headerlink" title="环境配置"></a>环境配置</h2>
                  <p>在这之前，我们需要先配置一下环境，我的Python的版本为2.7，需要额外安装的库有两个，一个是Beautiful Soup，一个是MySQLdb，在这里附上两个库的下载地址， <a href="https://pypi.python.org/pypi/beautifulsoup4/4.3.2" target="_blank" rel="noopener">Beautiful Soup</a> <a href="http://sourceforge.net/projects/mysql-python/" target="_blank" rel="noopener">MySQLdb</a> 大家可以下载之后通过如下命令安装</p>
                  <figure class="highlight vim">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="keyword">python</span> setup.<span class="keyword">py</span> install</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>环境配置好之后，我们便可以开心地撸爬虫了</p>
                  <h2 id="框架思路"><a href="#框架思路" class="headerlink" title="框架思路"></a>框架思路</h2>
                  <p>首先我们随便找一个分类地址，<a href="http://iask.sina.com.cn/c/978-all-1.html" target="_blank" rel="noopener">外语学习 - 爱问知识人</a>，打开之后可以看到一系列的问题列表。 我们在这个页面需要获取的东西有： 总的页码数，每一页的所有问题链接。 接下来我们需要遍历所有的问题，来抓取每一个详情页面，提取问题，问题内容，回答者，回答时间，回答内容。 最后，我们需要把这些内容存储到数据库中。</p>
                  <h2 id="要点简析"><a href="#要点简析" class="headerlink" title="要点简析"></a>要点简析</h2>
                  <p>其实大部分内容相信大家会了前面的内容，这里的爬虫思路已经融汇贯通了，这里就说一下一些扩展的功能</p>
                  <h3 id="1-日志输出"><a href="#1-日志输出" class="headerlink" title="1.日志输出"></a>1.日志输出</h3>
                  <p>日志输出，我们要输出时间和爬取的状态，比如像下面这样：</p>
                  <blockquote>
                    <p>[2015-08-10 03:05:20] 113011 号问题存在其他答案 我个人认为应该是樱桃沟很美的 [2015-08-10 03:05:20] 保存到数据库,此问题的ID为 113011 [2015-08-10 03:05:20] 当前爬取第 2 的内容,发现一个问题 百度有一个地方，花儿带着芳香，水儿流淌奔腾是什么意思 多多帮忙哦 回答数量 1 [2015-08-10 03:05:19] 保存到数据库,此问题的ID为 113010</p>
                  </blockquote>
                  <p>所以，我们需要引入时间函数，然后写一个获取当前时间的函数</p>
                  <figure class="highlight pgsql">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="keyword">import</span> <span class="type">time</span></span><br><span class="line"></span><br><span class="line">#获取当前时间</span><br><span class="line">def getCurrentTime(self):</span><br><span class="line">    <span class="keyword">return</span> <span class="type">time</span>.strftime(<span class="string">'[%Y-%m-%d %H:%M:%S]'</span>,<span class="type">time</span>.<span class="built_in">localtime</span>(<span class="type">time</span>.time()))</span><br><span class="line">    </span><br><span class="line">#获取当前时间</span><br><span class="line">def getCurrentDate(self):</span><br><span class="line">    <span class="keyword">return</span> <span class="type">time</span>.strftime(<span class="string">'%Y-%m-%d'</span>,<span class="type">time</span>.<span class="built_in">localtime</span>(<span class="type">time</span>.time()))</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>以上分别是获取带具体时间和获取日期的函数，在输出时，我们可以在输出语句的前面调用这函数即可。 然后我们需要将缓冲区设置输出到log中，在程序的最前面加上这两句即可</p>
                  <figure class="highlight ini">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="attr">f_handler</span>=open(<span class="string">'out.log'</span>, <span class="string">'w'</span>) </span><br><span class="line"><span class="attr">sys.stdout</span>=f_handler</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>这样，所有的print语句输出的内容就会保存到out.log文件中了。</p>
                  <h3 id="2-页码保存"><a href="#2-页码保存" class="headerlink" title="2.页码保存"></a>2.页码保存</h3>
                  <p>爬虫爬取过程中可能出现各种各样的错误，这样会导致爬虫的中断，如果我们重新运行爬虫，那么就会导致爬虫从头开始运行了，这样显然是不合理的。所以，我们需要把当前爬取的页面保存下来，比如可以保存到文本中，假如爬虫中断了，重新运行爬虫，读取文本文件的内容，接着爬取即可。 大家可以稍微参考一下函数的实现：</p>
                  <figure class="highlight routeros">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="comment">#主函数</span></span><br><span class="line">def main(self):</span><br><span class="line">    <span class="attribute">f_handler</span>=open('out.log', <span class="string">'w'</span>) </span><br><span class="line">    sys.<span class="attribute">stdout</span>=f_handler</span><br><span class="line">   <span class="built_in"> page </span>= open(<span class="string">'page.txt'</span>, <span class="string">'r'</span>)</span><br><span class="line">    content = page.readline()</span><br><span class="line">    start_page = int(content.strip()) - 1</span><br><span class="line">    page.close()     </span><br><span class="line">    <span class="builtin-name">print</span> self.getCurrentTime(),<span class="string">"开始页码"</span>,start_page</span><br><span class="line">    <span class="builtin-name">print</span> self.getCurrentTime(),<span class="string">"爬虫正在启动,开始爬取爱问知识人问题"</span></span><br><span class="line">    self.total_num = self.getTotalPageNum()</span><br><span class="line">    <span class="builtin-name">print</span> self.getCurrentTime(),<span class="string">"获取到目录页面个数"</span>,self.total_num,<span class="string">"个"</span></span><br><span class="line">    <span class="keyword">if</span> <span class="keyword">not</span> start_page:</span><br><span class="line">        start_page = self.total_num</span><br><span class="line">    <span class="keyword">for</span> x <span class="keyword">in</span> range(1,start_page):</span><br><span class="line">        <span class="builtin-name">print</span> self.getCurrentTime(),<span class="string">"正在抓取第"</span>,start_page-x+1,<span class="string">"个页面"</span></span><br><span class="line">        try:</span><br><span class="line">            self.getQuestions(start_page-x+1)</span><br><span class="line">        except urllib2.URLError, e:</span><br><span class="line">            <span class="keyword">if</span> hasattr(e, <span class="string">"reason"</span>):</span><br><span class="line">                <span class="builtin-name">print</span> self.getCurrentTime(),<span class="string">"某总页面内抓取或提取失败,错误原因"</span>, e.reason</span><br><span class="line">        except Exception,e:  </span><br><span class="line">            <span class="builtin-name">print</span> self.getCurrentTime(),<span class="string">"某总页面内抓取或提取失败,错误原因:"</span>,e</span><br><span class="line">        <span class="keyword">if</span> start_page-x+1 &lt; start_page:</span><br><span class="line">            <span class="attribute">f</span>=open('page.txt','w')</span><br><span class="line">            f.write(str(start_page-x+1))</span><br><span class="line">            <span class="builtin-name">print</span> self.getCurrentTime(),<span class="string">"写入新页码"</span>,start_page-x+1</span><br><span class="line">            f.close()</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>这样，不管我们爬虫中途遇到什么错误，妈妈也不会担心了</p>
                  <h3 id="3-页面处理"><a href="#3-页面处理" class="headerlink" title="3.页面处理"></a>3.页面处理</h3>
                  <p>页面处理过程中，我们可能遇到各种各样奇葩的HTML代码，和上一节一样，我们沿用一个页面处理类即可。</p>
                  <figure class="highlight vbnet">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">import re</span><br><span class="line"></span><br><span class="line"><span class="meta">#处理页面标签类</span></span><br><span class="line"><span class="keyword">class</span> Tool:</span><br><span class="line">    </span><br><span class="line">    <span class="meta">#将超链接广告剔除</span></span><br><span class="line">    removeADLink = re.compile(<span class="comment">'<span class="doctag">&lt;div class="link_layer.*?&lt;/div&gt;</span>')</span></span><br><span class="line">    <span class="meta">#去除img标签,1-7位空格,&amp;nbsp;</span></span><br><span class="line">    removeImg = re.compile(<span class="comment">'<span class="doctag">&lt;img.*?&gt;</span>| &#123;1,7&#125;|&amp;nbsp;')</span></span><br><span class="line">    <span class="meta">#删除超链接标签</span></span><br><span class="line">    removeAddr = re.compile(<span class="comment">'<span class="doctag">&lt;a.*?&gt;</span>|<span class="doctag">&lt;/a&gt;</span>')</span></span><br><span class="line">    <span class="meta">#把换行的标签换为\n</span></span><br><span class="line">    replaceLine = re.compile(<span class="comment">'<span class="doctag">&lt;tr&gt;</span>|<span class="doctag">&lt;div&gt;</span>|<span class="doctag">&lt;/div&gt;</span>|<span class="doctag">&lt;/p&gt;</span>')</span></span><br><span class="line">    <span class="meta">#将表格制表&lt;td&gt;替换为\t</span></span><br><span class="line">    replaceTD= re.compile(<span class="comment">'<span class="doctag">&lt;td&gt;</span>')</span></span><br><span class="line">    <span class="meta">#将换行符或双换行符替换为\n</span></span><br><span class="line">    replaceBR = re.compile(<span class="comment">'<span class="doctag">&lt;br&gt;</span><span class="doctag">&lt;br&gt;</span>|<span class="doctag">&lt;br&gt;</span>')</span></span><br><span class="line">    <span class="meta">#将其余标签剔除</span></span><br><span class="line">    removeExtraTag = re.compile(<span class="comment">'<span class="doctag">&lt;.*?&gt;</span>')</span></span><br><span class="line">    <span class="meta">#将多行空行删除</span></span><br><span class="line">    removeNoneLine = re.compile(<span class="comment">'\n+')</span></span><br><span class="line">    </span><br><span class="line">    def replace(self,x):</span><br><span class="line">        x = re.<span class="keyword">sub</span>(self.removeADLink,<span class="string">""</span>,x)</span><br><span class="line">        x = re.<span class="keyword">sub</span>(self.removeImg,<span class="string">""</span>,x)</span><br><span class="line">        x = re.<span class="keyword">sub</span>(self.removeAddr,<span class="string">""</span>,x)</span><br><span class="line">        x = re.<span class="keyword">sub</span>(self.replaceLine,<span class="string">"\n"</span>,x)</span><br><span class="line">        x = re.<span class="keyword">sub</span>(self.replaceTD,<span class="string">"\t"</span>,x)</span><br><span class="line">        x = re.<span class="keyword">sub</span>(self.replaceBR,<span class="string">"\n"</span>,x)</span><br><span class="line">        x = re.<span class="keyword">sub</span>(self.removeExtraTag,<span class="string">""</span>,x)</span><br><span class="line">        x = re.<span class="keyword">sub</span>(self.removeNoneLine,<span class="string">"\n"</span>,x)</span><br><span class="line">        <span class="meta">#strip()将前后多余内容删除</span></span><br><span class="line">        <span class="keyword">return</span> x.strip()</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>我们可以用一段含有HTML代码的文字，经过调用replace方法之后，各种冗余的HTML代码就会处理好了。 比如我们这么一段代码：</p>
                  <figure class="highlight javascript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">&lt;article <span class="class"><span class="keyword">class</span></span>=<span class="string">"article-content"</span>&gt;</span><br><span class="line">&lt;h2&gt;前言&lt;<span class="regexp">/h2&gt;</span></span><br><span class="line"><span class="regexp">&lt;p&gt;最近发现MySQL服务隔三差五就会挂掉，导致我的网站和爬虫都无法正常运作。自己的网站是基于MySQL，在做爬虫存取一些资料的时候也是基于MySQL，数据量一大了，MySQL它就有点受不了了，时不时会崩掉，虽然我自己有网站监控和邮件通知，但是好多时候还是需要我来手动连接我的服务器重新启动一下我的MySQL，这样简直太不友好了，所以，我就觉定自己写个脚本，定时监控它，如果发现它挂掉了就重启它。&lt;/</span>p&gt;</span><br><span class="line">&lt;p&gt;好了，闲言碎语不多讲，开始我们的配置之旅。&lt;<span class="regexp">/p&gt;</span></span><br><span class="line"><span class="regexp">&lt;p&gt;运行环境：&lt;strong&gt;Ubuntu Linux 14.04&lt;/</span>strong&gt;&lt;<span class="regexp">/p&gt;</span></span><br><span class="line"><span class="regexp">&lt;h2&gt;编写Shell脚本&lt;/</span>h2&gt;</span><br><span class="line">&lt;p&gt;首先，我们要编写一个shell脚本，脚本主要执行的逻辑如下：&lt;<span class="regexp">/p&gt;</span></span><br><span class="line"><span class="regexp">&lt;p&gt;显示mysqld进程状态，如果判断进程未在运行，那么输出日志到文件，然后启动mysql服务，如果进程在运行，那么不执行任何操作，可以选择性输出监测结果。&lt;/</span>p&gt;</span><br><span class="line">&lt;p&gt;可能大家对于shell脚本比较陌生，在这里推荐官方的shell脚本文档来参考一下&lt;<span class="regexp">/p&gt;</span></span><br><span class="line"><span class="regexp">&lt;p&gt;&lt;a href="http:/</span><span class="regexp">/wiki.ubuntu.org.cn/</span>Shell%E7%BC%<span class="number">96</span>%E7%A8%<span class="number">8</span>B%E5%<span class="number">9</span>F%BA%E7%A1%<span class="number">80</span><span class="string">" data-original-title="</span><span class="string">" title="</span><span class="string">"&gt;Ubuntu Shell 编程基础&lt;/a&gt;&lt;/p&gt;</span></span><br><span class="line"><span class="string">&lt;p&gt;shell脚本的后缀为sh，在任何位置新建一个脚本文件，我选择在 /etc/mysql 目录下新建一个 listen.sh 文件。&lt;/p&gt;</span></span><br><span class="line"><span class="string">&lt;p&gt;执行如下命令：&lt;/p&gt;</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>经过处理后便会变成如下的样子：</p>
                  <figure class="highlight dockerfile">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">前言</span><br><span class="line">最近发现MySQL服务隔三差五就会挂掉，导致我的网站和爬虫都无法正常运作。自己的网站是基于MySQL，在做爬虫存取一些资料的时候也是基于MySQL，数据量一大了，MySQL它就有点受不了了，时不时会崩掉，虽然我自己有网站监控和邮件通知，但是好多时候还是需要我来手动连接我的服务器重新启动一下我的MySQL，这样简直太不友好了，所以，我就觉定自己写个脚本，定时监控它，如果发现它挂掉了就重启它。</span><br><span class="line">好了，闲言碎语不多讲，开始我们的配置之旅。</span><br><span class="line">运行环境：UbuntuLinux14.<span class="number">04</span></span><br><span class="line">编写<span class="keyword">Shell</span><span class="bash">脚本</span></span><br><span class="line">首先，我们要编写一个<span class="keyword">shell</span><span class="bash">脚本，脚本主要执行的逻辑如下：</span></span><br><span class="line">显示mysqld进程状态，如果判断进程未在运行，那么输出日志到文件，然后启动mysql服务，如果进程在运行，那么不执行任何操作，可以选择性输出监测结果。</span><br><span class="line">可能大家对于<span class="keyword">shell</span><span class="bash">脚本比较陌生，在这里推荐官方的shell脚本文档来参考一下</span></span><br><span class="line">UbuntuShell编程基础</span><br><span class="line"><span class="keyword">shell</span><span class="bash">脚本的后缀为sh，在任何位置新建一个脚本文件，我选择在/etc/mysql目录下新建一个listen.sh文件。</span></span><br><span class="line">执行如下命令：</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>经过上面的处理，所有乱乱的代码都会被处理好了。</p>
                  <h3 id="4-保存到数据库"><a href="#4-保存到数据库" class="headerlink" title="4.保存到数据库"></a>4.保存到数据库</h3>
                  <p>在这里，我们想实现一个通用的方法，就是把存储的一个个内容变成字典的形式，然后执行插入语句的时候，自动构建对应的sql语句，插入数据。 比如我们构造如下的字典：</p>
                  <figure class="highlight prolog">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">#构造最佳答案的字典</span><br><span class="line">good_ans_dict = &#123;</span><br><span class="line">        <span class="string">"text"</span>: good_ans[<span class="number">0</span>],</span><br><span class="line">        <span class="string">"answerer"</span>: good_ans[<span class="number">1</span>],</span><br><span class="line">        <span class="string">"date"</span>: good_ans[<span class="number">2</span>],</span><br><span class="line">        <span class="string">"is_good"</span>: str(good_ans[<span class="number">3</span>]),</span><br><span class="line">        <span class="string">"question_id"</span>: str(insert_id)</span><br><span class="line">        &#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>构造sql语句并插入到数据库的方法如下：</p>
                  <figure class="highlight php">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="comment">#插入数据</span></span><br><span class="line">    def insertData(<span class="keyword">self</span>, table, my_dict):</span><br><span class="line">         <span class="keyword">try</span>:</span><br><span class="line">             <span class="keyword">self</span>.db.set_character_set(<span class="string">'utf8'</span>)</span><br><span class="line">             cols = <span class="string">', '</span>.join(my_dict.keys())</span><br><span class="line">             values = <span class="string">'"," '</span>.join(my_dict.values())</span><br><span class="line">             sql = <span class="string">"INSERT INTO %s (%s) VALUES (%s)"</span> % (table, cols, <span class="string">'"'</span>+values+<span class="string">'"'</span>)</span><br><span class="line">             <span class="keyword">try</span>:</span><br><span class="line">                 result = <span class="keyword">self</span>.cur.execute(sql)</span><br><span class="line">                 insert_id = <span class="keyword">self</span>.db.insert_id()</span><br><span class="line">                 <span class="keyword">self</span>.db.commit()</span><br><span class="line">                 <span class="comment">#判断是否执行成功</span></span><br><span class="line">                 <span class="keyword">if</span> result:</span><br><span class="line">                     <span class="keyword">return</span> insert_id</span><br><span class="line">                 <span class="keyword">else</span>:</span><br><span class="line">                     <span class="keyword">return</span> <span class="number">0</span></span><br><span class="line">             except MySQLdb.Error,e:</span><br><span class="line">                 <span class="comment">#发生错误时回滚</span></span><br><span class="line">                 <span class="keyword">self</span>.db.rollback()</span><br><span class="line">                 <span class="comment">#主键唯一，无法插入</span></span><br><span class="line">                 <span class="keyword">if</span> <span class="string">"key 'PRIMARY'"</span> in e.args[<span class="number">1</span>]:</span><br><span class="line">                     <span class="keyword">print</span> <span class="keyword">self</span>.getCurrentTime(),<span class="string">"数据已存在，未插入数据"</span></span><br><span class="line">                 <span class="keyword">else</span>:</span><br><span class="line">                     <span class="keyword">print</span> <span class="keyword">self</span>.getCurrentTime(),<span class="string">"插入数据失败，原因 %d: %s"</span> % (e.args[<span class="number">0</span>], e.args[<span class="number">1</span>])</span><br><span class="line">         except MySQLdb.Error,e:</span><br><span class="line">             <span class="keyword">print</span> <span class="keyword">self</span>.getCurrentTime(),<span class="string">"数据库错误，原因%d: %s"</span> % (e.args[<span class="number">0</span>], e.args[<span class="number">1</span>])</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>这里我们只需要传入那个字典，便会构建出对应字典键值和键名的sql语句，完成插入。</p>
                  <h3 id="5-PHP读取日志"><a href="#5-PHP读取日志" class="headerlink" title="5.PHP读取日志"></a>5.PHP读取日志</h3>
                  <p>我们将运行结果输出到了日志里，那么怎么查看日志呢？很简单，在这里提供两种方法 方法一： PHP倒序输出所有日志内容</p>
                  <figure class="highlight xml">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="tag">&lt;<span class="name">html</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">"utf-8"</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">meta</span> <span class="attr">http-equiv</span>=<span class="string">"refresh"</span> <span class="attr">content</span> = <span class="string">"5"</span>&gt;</span> </span><br><span class="line">    <span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">        <span class="php"><span class="meta">&lt;?php</span></span></span><br><span class="line"><span class="php">            $fp = file(<span class="string">"out.log"</span>);</span></span><br><span class="line"><span class="php">            <span class="keyword">if</span> ($fp) &#123;</span></span><br><span class="line"><span class="php">                <span class="keyword">for</span>($i = count($fp) - <span class="number">1</span>;$i &gt;= <span class="number">0</span>; $i --) </span></span><br><span class="line"><span class="php">                <span class="keyword">echo</span> $fp[$i].<span class="string">"&lt;br&gt;"</span>;</span></span><br><span class="line"><span class="php">            &#125;</span></span><br><span class="line"><span class="php">        <span class="meta">?&gt;</span></span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>此方法可以看到所有的输入日志，但是如果日志太大了，那么就会报耗费内存太大，无法输出。为此我们就有了第二种方法，利用linux命令，输出后十行内容。 方法二：</p>
                  <figure class="highlight xml">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="tag">&lt;<span class="name">html</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">"utf-8"</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">meta</span> <span class="attr">http-equiv</span>=<span class="string">"refresh"</span> <span class="attr">content</span> = <span class="string">"5"</span>&gt;</span> </span><br><span class="line">    <span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">		<span class="php"><span class="meta">&lt;?php</span> </span></span><br><span class="line"><span class="php">			$ph = popen(<span class="string">'tail -n 100 out.log'</span>,<span class="string">'r'</span>);</span></span><br><span class="line"><span class="php">			<span class="keyword">while</span>($r = fgets($ph))&#123;</span></span><br><span class="line"><span class="php">				<span class="keyword">echo</span> $r.<span class="string">"&lt;br&gt;"</span>;</span></span><br><span class="line"><span class="php">			&#125;</span></span><br><span class="line"><span class="php">			pclose($ph);</span></span><br><span class="line"><span class="php">		<span class="meta">?&gt;</span></span></span><br><span class="line">	<span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>上面两种方法都是5秒刷新一次网页来查看最新的日志。</p>
                  <h2 id="源代码放送"><a href="#源代码放送" class="headerlink" title="源代码放送"></a>源代码放送</h2>
                  <p>好了，闲言碎语不多讲，直接上源码了</p>
                  <figure class="highlight css">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="selector-tag">spider</span><span class="selector-class">.py</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <figure class="highlight python">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="comment"># -*- coding:utf-8 -*-</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> urllib</span><br><span class="line"><span class="keyword">import</span> urllib2</span><br><span class="line"><span class="keyword">import</span> re</span><br><span class="line"><span class="keyword">import</span> time</span><br><span class="line"><span class="keyword">import</span> types</span><br><span class="line"><span class="keyword">import</span> page</span><br><span class="line"><span class="keyword">import</span> mysql</span><br><span class="line"><span class="keyword">import</span> sys</span><br><span class="line"><span class="keyword">from</span> bs4 <span class="keyword">import</span> BeautifulSoup</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Spider</span>:</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">#初始化</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self)</span>:</span></span><br><span class="line">        self.page_num = <span class="number">1</span></span><br><span class="line">        self.total_num = <span class="literal">None</span></span><br><span class="line">        self.page_spider = page.Page()</span><br><span class="line">        self.mysql = mysql.Mysql()</span><br><span class="line">        </span><br><span class="line">    <span class="comment">#获取当前时间</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">getCurrentTime</span><span class="params">(self)</span>:</span></span><br><span class="line">        <span class="keyword">return</span> time.strftime(<span class="string">'[%Y-%m-%d %H:%M:%S]'</span>,time.localtime(time.time()))</span><br><span class="line">    </span><br><span class="line">    <span class="comment">#获取当前时间</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">getCurrentDate</span><span class="params">(self)</span>:</span></span><br><span class="line">        <span class="keyword">return</span> time.strftime(<span class="string">'%Y-%m-%d'</span>,time.localtime(time.time()))</span><br><span class="line">    </span><br><span class="line">    <span class="comment">#通过网页的页码数来构建网页的URL</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">getPageURLByNum</span><span class="params">(self, page_num)</span>:</span></span><br><span class="line">        page_url = <span class="string">"http://iask.sina.com.cn/c/978-all-"</span> + str(page_num) + <span class="string">".html"</span></span><br><span class="line">        <span class="keyword">return</span> page_url</span><br><span class="line">    </span><br><span class="line">    </span><br><span class="line">    <span class="comment">#通过传入网页页码来获取网页的HTML</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">getPageByNum</span><span class="params">(self, page_num)</span>:</span></span><br><span class="line">        request = urllib2.Request(self.getPageURLByNum(page_num))</span><br><span class="line">        <span class="keyword">try</span>:</span><br><span class="line">            response = urllib2.urlopen(request)</span><br><span class="line">        <span class="keyword">except</span> urllib2.URLError, e:</span><br><span class="line">            <span class="keyword">if</span> hasattr(e, <span class="string">"code"</span>):</span><br><span class="line">                <span class="keyword">print</span> self.getCurrentTime(),<span class="string">"获取页面失败,错误代号"</span>, e.code</span><br><span class="line">                <span class="keyword">return</span> <span class="literal">None</span></span><br><span class="line">            <span class="keyword">if</span> hasattr(e, <span class="string">"reason"</span>):</span><br><span class="line">                <span class="keyword">print</span> self.getCurrentTime(),<span class="string">"获取页面失败,原因"</span>, e.reason</span><br><span class="line">                <span class="keyword">return</span> <span class="literal">None</span></span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            page =  response.read().decode(<span class="string">"utf-8"</span>)</span><br><span class="line">            <span class="keyword">return</span> page</span><br><span class="line">    </span><br><span class="line">    <span class="comment">#获取所有的页码数</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">getTotalPageNum</span><span class="params">(self)</span>:</span></span><br><span class="line">        <span class="keyword">print</span> self.getCurrentTime(),<span class="string">"正在获取目录页面个数,请稍候"</span></span><br><span class="line">        page = self.getPageByNum(<span class="number">1</span>)</span><br><span class="line">        <span class="comment">#匹配所有的页码数,\u4e0b\u4e00\u9875是下一页的UTF8编码</span></span><br><span class="line">        pattern = re.compile(<span class="string">u'&lt;span class="more".*?&gt;.*?&lt;span.*?&lt;a href.*?class=""&gt;(.*?)&lt;/a&gt;\s*&lt;a.*?\u4e0b\u4e00\u9875&lt;/a&gt;'</span>, re.S)</span><br><span class="line">        match = re.search(pattern, page)</span><br><span class="line">        <span class="keyword">if</span> match:</span><br><span class="line">            <span class="keyword">return</span> match.group(<span class="number">1</span>)</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            <span class="keyword">print</span> self.getCurrentTime(),<span class="string">"获取总页码失败"</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">#分析问题的代码,得到问题的提问者,问题内容,回答个数,提问时间</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">getQuestionInfo</span><span class="params">(self, question)</span>:</span></span><br><span class="line">        <span class="keyword">if</span> <span class="keyword">not</span> type(question) <span class="keyword">is</span> types.StringType:</span><br><span class="line">            question = str(question)</span><br><span class="line">        <span class="comment">#print question</span></span><br><span class="line">        pattern = re.compile(<span class="string">u'&lt;span.*?question-face.*?&gt;.*?&lt;img.*?alt="(.*?)".*?&lt;/span&gt;.*?&lt;a href="(.*?)".*?&gt;(.*?)&lt;/a&gt;.*?answer_num.*?&gt;(\d*).*?&lt;/span&gt;.*?answer_time.*?&gt;(.*?)&lt;/span&gt;'</span>, re.S)</span><br><span class="line">        match = re.search(pattern, question)</span><br><span class="line">        <span class="keyword">if</span> match:</span><br><span class="line">            <span class="comment">#获得提问者</span></span><br><span class="line">            author = match.group(<span class="number">1</span>)</span><br><span class="line">            <span class="comment">#问题链接</span></span><br><span class="line">            href = match.group(<span class="number">2</span>)</span><br><span class="line">            <span class="comment">#问题详情</span></span><br><span class="line">            text = match.group(<span class="number">3</span>)</span><br><span class="line">            <span class="comment">#回答个数</span></span><br><span class="line">            ans_num = match.group(<span class="number">4</span>)</span><br><span class="line">            <span class="comment">#回答时间</span></span><br><span class="line">            time = match.group(<span class="number">5</span>)</span><br><span class="line">            time_pattern = re.compile(<span class="string">'\d&#123;4&#125;\-\d&#123;2&#125;\-\d&#123;2&#125;'</span>, re.S)</span><br><span class="line">            time_match = re.search(time_pattern, time)</span><br><span class="line">            <span class="keyword">if</span> <span class="keyword">not</span> time_match:</span><br><span class="line">                time = self.getCurrentDate()</span><br><span class="line">            <span class="keyword">return</span> [author, href, text, ans_num, time]</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">None</span></span><br><span class="line">        </span><br><span class="line">    <span class="comment">#获取全部问题</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">getQuestions</span><span class="params">(self, page_num)</span>:</span></span><br><span class="line">        <span class="comment">#获得目录页面的HTML</span></span><br><span class="line">        page = self.getPageByNum(page_num)</span><br><span class="line">        soup = BeautifulSoup(page)</span><br><span class="line">        <span class="comment">#分析获得所有问题</span></span><br><span class="line">        questions = soup.select(<span class="string">"div.question_list ul li"</span>)</span><br><span class="line">        <span class="comment">#遍历每一个问题</span></span><br><span class="line">        <span class="keyword">for</span> question <span class="keyword">in</span> questions:</span><br><span class="line">            <span class="comment">#获得问题的详情</span></span><br><span class="line">            info = self.getQuestionInfo(question)</span><br><span class="line">            <span class="keyword">if</span> info:</span><br><span class="line">                <span class="comment">#得到问题的URL</span></span><br><span class="line">                url = <span class="string">"http://iask.sina.com.cn/"</span> + info[<span class="number">1</span>]</span><br><span class="line">                <span class="comment">#通过URL来获取问题的最佳答案和其他答案</span></span><br><span class="line">                ans = self.page_spider.getAnswer(url)</span><br><span class="line">                <span class="keyword">print</span> self.getCurrentTime(),<span class="string">"当前爬取第"</span>,page_num,<span class="string">"的内容,发现一个问题"</span>,info[<span class="number">2</span>],<span class="string">"回答数量"</span>,info[<span class="number">3</span>]</span><br><span class="line">                <span class="comment">#构造问题的字典,插入问题</span></span><br><span class="line">                ques_dict = &#123;</span><br><span class="line">                            <span class="string">"text"</span>: info[<span class="number">2</span>],</span><br><span class="line">                            <span class="string">"questioner"</span>: info[<span class="number">0</span>],</span><br><span class="line">                            <span class="string">"date"</span>: info[<span class="number">4</span>],</span><br><span class="line">                            <span class="string">"ans_num"</span>: info[<span class="number">3</span>],</span><br><span class="line">                            <span class="string">"url"</span>: url</span><br><span class="line">                            &#125;</span><br><span class="line">                <span class="comment">#获得插入的问题的自增ID </span></span><br><span class="line">                insert_id = self.mysql.insertData(<span class="string">"iask_questions"</span>,ques_dict)</span><br><span class="line">                <span class="comment">#得到最佳答案</span></span><br><span class="line">                good_ans = ans[<span class="number">0</span>]</span><br><span class="line">                <span class="keyword">print</span> self.getCurrentTime(),<span class="string">"保存到数据库,此问题的ID为"</span>,insert_id</span><br><span class="line">                <span class="comment">#如果存在最佳答案,那么就插入</span></span><br><span class="line">                <span class="keyword">if</span> good_ans:</span><br><span class="line">                    <span class="keyword">print</span> self.getCurrentTime(),insert_id,<span class="string">"号问题存在最佳答案"</span>,good_ans[<span class="number">0</span>]</span><br><span class="line">                    <span class="comment">#构造最佳答案的字典</span></span><br><span class="line">                    good_ans_dict = &#123;</span><br><span class="line">                            <span class="string">"text"</span>: good_ans[<span class="number">0</span>],</span><br><span class="line">                            <span class="string">"answerer"</span>: good_ans[<span class="number">1</span>],</span><br><span class="line">                            <span class="string">"date"</span>: good_ans[<span class="number">2</span>],</span><br><span class="line">                            <span class="string">"is_good"</span>: str(good_ans[<span class="number">3</span>]),</span><br><span class="line">                            <span class="string">"question_id"</span>: str(insert_id)</span><br><span class="line">                            &#125;</span><br><span class="line">                    <span class="comment">#插入最佳答案</span></span><br><span class="line">                    <span class="keyword">if</span> self.mysql.insertData(<span class="string">"iask_answers"</span>,good_ans_dict):</span><br><span class="line">                        <span class="keyword">print</span> self.getCurrentTime(),<span class="string">"保存最佳答案成功"</span></span><br><span class="line">                    <span class="keyword">else</span>:</span><br><span class="line">                        <span class="keyword">print</span> self.getCurrentTime(),<span class="string">"保存最佳答案失败"</span></span><br><span class="line">                <span class="comment">#获得其他答案</span></span><br><span class="line">                other_anses = ans[<span class="number">1</span>]</span><br><span class="line">                <span class="comment">#遍历每一个其他答案</span></span><br><span class="line">                <span class="keyword">for</span> other_ans <span class="keyword">in</span> other_anses:</span><br><span class="line">                    <span class="comment">#如果答案存在</span></span><br><span class="line">                    <span class="keyword">if</span> other_ans:</span><br><span class="line">                        <span class="keyword">print</span> self.getCurrentTime(),insert_id,<span class="string">"号问题存在其他答案"</span>,other_ans[<span class="number">0</span>]</span><br><span class="line">                        <span class="comment">#构造其他答案的字典</span></span><br><span class="line">                        other_ans_dict = &#123;</span><br><span class="line">                                <span class="string">"text"</span>: other_ans[<span class="number">0</span>],</span><br><span class="line">                                <span class="string">"answerer"</span>: other_ans[<span class="number">1</span>],</span><br><span class="line">                                <span class="string">"date"</span>: other_ans[<span class="number">2</span>],</span><br><span class="line">                                <span class="string">"is_good"</span>: str(other_ans[<span class="number">3</span>]),</span><br><span class="line">                                <span class="string">"question_id"</span>: str(insert_id)</span><br><span class="line">                                &#125;</span><br><span class="line">                        <span class="comment">#插入这个答案</span></span><br><span class="line">                        <span class="keyword">if</span> self.mysql.insertData(<span class="string">"iask_answers"</span>,other_ans_dict):</span><br><span class="line">                            <span class="keyword">print</span> self.getCurrentTime(),<span class="string">"保存其他答案成功"</span></span><br><span class="line">                        <span class="keyword">else</span>:</span><br><span class="line">                            <span class="keyword">print</span> self.getCurrentTime(),<span class="string">"保存其他答案失败"</span></span><br><span class="line">        </span><br><span class="line">    <span class="comment">#主函数</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">main</span><span class="params">(self)</span>:</span></span><br><span class="line">        f_handler=open(<span class="string">'out.log'</span>, <span class="string">'w'</span>) </span><br><span class="line">        sys.stdout=f_handler</span><br><span class="line">        page = open(<span class="string">'page.txt'</span>, <span class="string">'r'</span>)</span><br><span class="line">        content = page.readline()</span><br><span class="line">        start_page = int(content.strip()) - <span class="number">1</span></span><br><span class="line">        page.close()     </span><br><span class="line">        <span class="keyword">print</span> self.getCurrentTime(),<span class="string">"开始页码"</span>,start_page</span><br><span class="line">        <span class="keyword">print</span> self.getCurrentTime(),<span class="string">"爬虫正在启动,开始爬取爱问知识人问题"</span></span><br><span class="line">        self.total_num = self.getTotalPageNum()</span><br><span class="line">        <span class="keyword">print</span> self.getCurrentTime(),<span class="string">"获取到目录页面个数"</span>,self.total_num,<span class="string">"个"</span></span><br><span class="line">        <span class="keyword">if</span> <span class="keyword">not</span> start_page:</span><br><span class="line">            start_page = self.total_num</span><br><span class="line">        <span class="keyword">for</span> x <span class="keyword">in</span> range(<span class="number">1</span>,start_page):</span><br><span class="line">            <span class="keyword">print</span> self.getCurrentTime(),<span class="string">"正在抓取第"</span>,start_page-x+<span class="number">1</span>,<span class="string">"个页面"</span></span><br><span class="line">            <span class="keyword">try</span>:</span><br><span class="line">                self.getQuestions(start_page-x+<span class="number">1</span>)</span><br><span class="line">            <span class="keyword">except</span> urllib2.URLError, e:</span><br><span class="line">                <span class="keyword">if</span> hasattr(e, <span class="string">"reason"</span>):</span><br><span class="line">                    <span class="keyword">print</span> self.getCurrentTime(),<span class="string">"某总页面内抓取或提取失败,错误原因"</span>, e.reason</span><br><span class="line">            <span class="keyword">except</span> Exception,e:  </span><br><span class="line">                <span class="keyword">print</span> self.getCurrentTime(),<span class="string">"某总页面内抓取或提取失败,错误原因:"</span>,e</span><br><span class="line">            <span class="keyword">if</span> start_page-x+<span class="number">1</span> &lt; start_page:</span><br><span class="line">                f=open(<span class="string">'page.txt'</span>,<span class="string">'w'</span>)</span><br><span class="line">                f.write(str(start_page-x+<span class="number">1</span>))</span><br><span class="line">                <span class="keyword">print</span> self.getCurrentTime(),<span class="string">"写入新页码"</span>,start_page-x+<span class="number">1</span></span><br><span class="line">                f.close()</span><br><span class="line"></span><br><span class="line">spider = Spider()</span><br><span class="line">spider.main()</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <figure class="highlight css">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="selector-tag">page</span><span class="selector-class">.py</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <figure class="highlight properties">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="comment"># -*- coding:utf-8 -*-</span></span><br><span class="line"><span class="attr">import</span> <span class="string">urllib</span></span><br><span class="line"><span class="attr">import</span> <span class="string">urllib2</span></span><br><span class="line"><span class="attr">import</span> <span class="string">re</span></span><br><span class="line"><span class="attr">import</span> <span class="string">time</span></span><br><span class="line"><span class="attr">import</span> <span class="string">types </span></span><br><span class="line"><span class="attr">import</span> <span class="string">tool</span></span><br><span class="line"><span class="attr">from</span> <span class="string">bs4 import BeautifulSoup</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#抓取分析某一问题和答案</span></span><br><span class="line"><span class="attr">class</span> <span class="string">Page:</span></span><br><span class="line">    </span><br><span class="line">    <span class="attr">def</span> <span class="string">__init__(self):</span></span><br><span class="line">        <span class="meta">self.tool</span> = <span class="string">tool.Tool()</span></span><br><span class="line">    </span><br><span class="line"><span class="comment">    #获取当前时间</span></span><br><span class="line">    <span class="attr">def</span> <span class="string">getCurrentDate(self):</span></span><br><span class="line">        <span class="attr">return</span> <span class="string">time.strftime('%Y-%m-%d',time.localtime(time.time()))</span></span><br><span class="line">    </span><br><span class="line"><span class="comment">    #获取当前时间</span></span><br><span class="line">    <span class="attr">def</span> <span class="string">getCurrentTime(self):</span></span><br><span class="line">        <span class="attr">return</span> <span class="string">time.strftime('[%Y-%m-%d %H:%M:%S]',time.localtime(time.time()))</span></span><br><span class="line"></span><br><span class="line"><span class="comment">    #通过页面的URL来获取页面的代码</span></span><br><span class="line">    <span class="attr">def</span> <span class="string">getPageByURL(self, url):</span></span><br><span class="line">        <span class="attr">try</span>:<span class="string"></span></span><br><span class="line">            <span class="attr">request</span> = <span class="string">urllib2.Request(url)</span></span><br><span class="line">            <span class="attr">response</span> = <span class="string">urllib2.urlopen(request)</span></span><br><span class="line">            <span class="attr">return</span> <span class="string">response.read().decode("utf-8") </span></span><br><span class="line">        <span class="attr">except</span> <span class="string">urllib2.URLError, e:</span></span><br><span class="line">            <span class="attr">if</span> <span class="string">hasattr(e, "code"):</span></span><br><span class="line">                <span class="attr">print</span> <span class="string">self.getCurrentTime(),"获取问题页面失败,错误代号", e.code</span></span><br><span class="line">                <span class="attr">return</span> <span class="string">None</span></span><br><span class="line">            <span class="attr">if</span> <span class="string">hasattr(e, "reason"):</span></span><br><span class="line">                <span class="attr">print</span> <span class="string">self.getCurrentTime(),"获取问题页面失败,原因", e.reason</span></span><br><span class="line">                <span class="attr">return</span> <span class="string">None</span></span><br><span class="line"></span><br><span class="line">    </span><br><span class="line"><span class="comment">    #传入一个List,返回它的标签里的内容,如果为空返回None</span></span><br><span class="line">    <span class="attr">def</span> <span class="string">getText(self, html):</span></span><br><span class="line">        <span class="attr">if</span> <span class="string">not type(html) is types.StringType:</span></span><br><span class="line">            <span class="attr">html</span> = <span class="string">str(html)</span></span><br><span class="line"><span class="comment">        #提取出&lt;pre&gt;标签里的内容</span></span><br><span class="line">        <span class="attr">pattern</span> = <span class="string">re.compile('&lt;pre.*?&gt;(.*?)&lt;/pre&gt;', re.S)</span></span><br><span class="line">        <span class="attr">match</span> = <span class="string">re.search(pattern, html)</span></span><br><span class="line"><span class="comment">        #如果匹配成功</span></span><br><span class="line">        <span class="attr">if</span> <span class="string">match:</span></span><br><span class="line">            <span class="attr">return</span> <span class="string">match.group(1)</span></span><br><span class="line">        <span class="attr">else</span>: <span class="string"></span></span><br><span class="line">            <span class="attr">return</span> <span class="string">None</span></span><br><span class="line">    </span><br><span class="line"><span class="comment">    #传入最佳答案的HTML,分析出回答者和回答时间</span></span><br><span class="line">    <span class="attr">def</span> <span class="string">getGoodAnswerInfo(self, html):</span></span><br><span class="line">        <span class="attr">pattern</span> = <span class="string">re.compile('"answer_tip.*?&lt;a.*?&gt;(.*?)&lt;/a&gt;.*?&lt;span class="time.*?&gt;.*?\|(.*?)&lt;/span&gt;', re.S)</span></span><br><span class="line">        <span class="attr">match</span> = <span class="string">re.search(pattern, html)</span></span><br><span class="line"><span class="comment">        #如果匹配,返回回答者和回答时间</span></span><br><span class="line">        <span class="attr">if</span> <span class="string">match:</span></span><br><span class="line">            <span class="attr">time</span> = <span class="string">match.group(2)</span></span><br><span class="line">            <span class="attr">time_pattern</span> = <span class="string">re.compile('\d&#123;2&#125;\-\d&#123;2&#125;\-\d&#123;2&#125;', re.S)</span></span><br><span class="line">            <span class="attr">time_match</span> = <span class="string">re.search(time_pattern, time)</span></span><br><span class="line">            <span class="attr">if</span> <span class="string">not time_match:</span></span><br><span class="line">                <span class="attr">time</span> = <span class="string">self.getCurrentDate()</span></span><br><span class="line">            <span class="attr">else</span>:<span class="string"></span></span><br><span class="line">                <span class="attr">time</span> = <span class="string">"20"+time</span></span><br><span class="line">            <span class="attr">return</span> <span class="string">[match.group(1),time]</span></span><br><span class="line">        <span class="attr">else</span>:<span class="string"></span></span><br><span class="line">            <span class="attr">return</span> <span class="string">[None,None]</span></span><br><span class="line">    </span><br><span class="line"><span class="comment">    #获得最佳答案</span></span><br><span class="line">    <span class="attr">def</span> <span class="string">getGoodAnswer(self, page):</span></span><br><span class="line">        <span class="attr">soup</span> = <span class="string">BeautifulSoup(page)</span></span><br><span class="line">        <span class="attr">text</span> = <span class="string">soup.select("div.good_point div.answer_text pre")</span></span><br><span class="line">        <span class="attr">if</span> <span class="string">len(text) &gt; 0:</span></span><br><span class="line"><span class="comment">            #获得最佳答案的内容</span></span><br><span class="line">            <span class="attr">ansText</span> = <span class="string">self.getText(str(text[0]))</span></span><br><span class="line">            <span class="attr">ansText</span> = <span class="string">self.tool.replace(ansText)</span></span><br><span class="line"><span class="comment">            #获得最佳答案的回答者信息</span></span><br><span class="line">            <span class="attr">info</span> = <span class="string">soup.select("div.good_point div.answer_tip")</span></span><br><span class="line">            <span class="attr">ansInfo</span> = <span class="string">self.getGoodAnswerInfo(str(info[0]))</span></span><br><span class="line"><span class="comment">            #将三者组合成一个List</span></span><br><span class="line">            <span class="attr">answer</span> = <span class="string">[ansText, ansInfo[0], ansInfo[1],1]</span></span><br><span class="line">            <span class="attr">return</span> <span class="string">answer</span></span><br><span class="line">        <span class="attr">else</span>:<span class="string"></span></span><br><span class="line"><span class="comment">            #如果不存在最佳答案,那么就返回空</span></span><br><span class="line">            <span class="attr">return</span> <span class="string">None</span></span><br><span class="line">    </span><br><span class="line"><span class="comment">    #传入回答者HTML,分析出回答者,回答时间</span></span><br><span class="line">    <span class="attr">def</span> <span class="string">getOtherAnswerInfo(self, html):</span></span><br><span class="line">        <span class="attr">if</span> <span class="string">not type(html) is types.StringType:</span></span><br><span class="line">            <span class="attr">html</span> = <span class="string">str(html)</span></span><br><span class="line">        <span class="attr">pattern</span> = <span class="string">re.compile('"author_name.*?&gt;(.*?)&lt;/a&gt;.*?answer_t"&gt;(.*?)&lt;/span&gt;', re.S)</span></span><br><span class="line">        <span class="attr">match</span> = <span class="string">re.search(pattern, html)</span></span><br><span class="line"><span class="comment">        #获得每一个回答的回答者信息和回答时间</span></span><br><span class="line">        <span class="attr">if</span> <span class="string">match:</span></span><br><span class="line">            <span class="attr">time</span> = <span class="string">match.group(2)</span></span><br><span class="line">            <span class="attr">time_pattern</span> = <span class="string">re.compile('\d&#123;2&#125;\-\d&#123;2&#125;\-\d&#123;2&#125;', re.S)</span></span><br><span class="line">            <span class="attr">time_match</span> = <span class="string">re.search(time_pattern, time)</span></span><br><span class="line">            <span class="attr">if</span> <span class="string">not time_match:</span></span><br><span class="line">                <span class="attr">time</span> = <span class="string">self.getCurrentDate()</span></span><br><span class="line">            <span class="attr">else</span>:<span class="string"></span></span><br><span class="line">                <span class="attr">time</span> = <span class="string">"20"+time</span></span><br><span class="line">            <span class="attr">return</span> <span class="string">[match.group(1),time]</span></span><br><span class="line">        <span class="attr">else</span>:<span class="string"></span></span><br><span class="line">            <span class="attr">return</span> <span class="string">[None,None]</span></span><br><span class="line">    </span><br><span class="line">            </span><br><span class="line"><span class="comment">    #获得其他答案</span></span><br><span class="line">    <span class="attr">def</span> <span class="string">getOtherAnswers(self, page):</span></span><br><span class="line">        <span class="attr">soup</span> = <span class="string">BeautifulSoup(page)</span></span><br><span class="line">        <span class="attr">results</span> =  <span class="string">soup.select("div.question_box li.clearfix .answer_info")</span></span><br><span class="line"><span class="comment">        #所有答案,包含好多个List,每个List包含了回答内容,回答者,回答时间</span></span><br><span class="line">        <span class="attr">answers</span> = <span class="string">[]</span></span><br><span class="line">        <span class="attr">for</span> <span class="string">result in results:</span></span><br><span class="line"><span class="comment">            #获得回答内容</span></span><br><span class="line">            <span class="attr">ansSoup</span> = <span class="string">BeautifulSoup(str(result))</span></span><br><span class="line">            <span class="attr">text</span> = <span class="string">ansSoup.select(".answer_txt span pre")</span></span><br><span class="line">            <span class="attr">ansText</span> = <span class="string">self.getText(str(text[0]))</span></span><br><span class="line">            <span class="attr">ansText</span> = <span class="string">self.tool.replace(ansText)</span></span><br><span class="line"><span class="comment">            #获得回答者和回答时间</span></span><br><span class="line">            <span class="attr">info</span> = <span class="string">ansSoup.select(".answer_tj")</span></span><br><span class="line">            <span class="attr">ansInfo</span> = <span class="string">self.getOtherAnswerInfo(info[0])</span></span><br><span class="line"><span class="comment">            #将三者组合成一个List</span></span><br><span class="line">            <span class="attr">answer</span> = <span class="string">[ansText, ansInfo[0], ansInfo[1],0]</span></span><br><span class="line"><span class="comment">            #加入到answers</span></span><br><span class="line">            <span class="attr">answers.append(answer)</span></span><br><span class="line">        <span class="attr">return</span> <span class="string">answers</span></span><br><span class="line">     </span><br><span class="line"><span class="comment">     #主函数</span></span><br><span class="line">    <span class="attr">def</span> <span class="string">getAnswer(self, url):</span></span><br><span class="line">        <span class="attr">if</span> <span class="string">not url:</span></span><br><span class="line">            <span class="attr">url</span> = <span class="string">"http://iask.sina.com.cn/b/gQiuSNCMV.html"</span></span><br><span class="line">        <span class="attr">page</span> = <span class="string">self.getPageByURL(url)</span></span><br><span class="line">        <span class="attr">good_ans</span> = <span class="string">self.getGoodAnswer(page)</span></span><br><span class="line">        <span class="attr">other_ans</span> = <span class="string">self.getOtherAnswers(page)</span></span><br><span class="line">        <span class="attr">return</span> <span class="string">[good_ans,other_ans]</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="attr">page</span> = <span class="string">Page()</span></span><br><span class="line"><span class="attr">page.getAnswer(None)</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <figure class="highlight css">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="selector-tag">tool</span><span class="selector-class">.py</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <figure class="highlight vbnet">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="meta">#-*- coding:utf-8 -*-</span></span><br><span class="line">import re</span><br><span class="line"></span><br><span class="line"><span class="meta">#处理页面标签类</span></span><br><span class="line"><span class="keyword">class</span> Tool:</span><br><span class="line">    </span><br><span class="line">    <span class="meta">#将超链接广告剔除</span></span><br><span class="line">    removeADLink = re.compile(<span class="comment">'<span class="doctag">&lt;div class="link_layer.*?&lt;/div&gt;</span>')</span></span><br><span class="line">    <span class="meta">#去除img标签,1-7位空格,&amp;nbsp;</span></span><br><span class="line">    removeImg = re.compile(<span class="comment">'<span class="doctag">&lt;img.*?&gt;</span>| &#123;1,7&#125;|&amp;nbsp;')</span></span><br><span class="line">    <span class="meta">#删除超链接标签</span></span><br><span class="line">    removeAddr = re.compile(<span class="comment">'<span class="doctag">&lt;a.*?&gt;</span>|<span class="doctag">&lt;/a&gt;</span>')</span></span><br><span class="line">    <span class="meta">#把换行的标签换为\n</span></span><br><span class="line">    replaceLine = re.compile(<span class="comment">'<span class="doctag">&lt;tr&gt;</span>|<span class="doctag">&lt;div&gt;</span>|<span class="doctag">&lt;/div&gt;</span>|<span class="doctag">&lt;/p&gt;</span>')</span></span><br><span class="line">    <span class="meta">#将表格制表&lt;td&gt;替换为\t</span></span><br><span class="line">    replaceTD= re.compile(<span class="comment">'<span class="doctag">&lt;td&gt;</span>')</span></span><br><span class="line">    <span class="meta">#将换行符或双换行符替换为\n</span></span><br><span class="line">    replaceBR = re.compile(<span class="comment">'<span class="doctag">&lt;br&gt;</span><span class="doctag">&lt;br&gt;</span>|<span class="doctag">&lt;br&gt;</span>')</span></span><br><span class="line">    <span class="meta">#将其余标签剔除</span></span><br><span class="line">    removeExtraTag = re.compile(<span class="comment">'<span class="doctag">&lt;.*?&gt;</span>')</span></span><br><span class="line">    <span class="meta">#将多行空行删除</span></span><br><span class="line">    removeNoneLine = re.compile(<span class="comment">'\n+')</span></span><br><span class="line">    </span><br><span class="line">    def replace(self,x):</span><br><span class="line">        x = re.<span class="keyword">sub</span>(self.removeADLink,<span class="string">""</span>,x)</span><br><span class="line">        x = re.<span class="keyword">sub</span>(self.removeImg,<span class="string">""</span>,x)</span><br><span class="line">        x = re.<span class="keyword">sub</span>(self.removeAddr,<span class="string">""</span>,x)</span><br><span class="line">        x = re.<span class="keyword">sub</span>(self.replaceLine,<span class="string">"\n"</span>,x)</span><br><span class="line">        x = re.<span class="keyword">sub</span>(self.replaceTD,<span class="string">"\t"</span>,x)</span><br><span class="line">        x = re.<span class="keyword">sub</span>(self.replaceBR,<span class="string">"\n"</span>,x)</span><br><span class="line">        x = re.<span class="keyword">sub</span>(self.removeExtraTag,<span class="string">""</span>,x)</span><br><span class="line">        x = re.<span class="keyword">sub</span>(self.removeNoneLine,<span class="string">"\n"</span>,x)</span><br><span class="line">        <span class="meta">#strip()将前后多余内容删除</span></span><br><span class="line">        <span class="keyword">return</span> x.strip()</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <figure class="highlight css">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="selector-tag">mysql</span><span class="selector-class">.py</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <figure class="highlight ruby">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="comment"># -*- coding:utf-8 -*-</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">import MySQLdb</span><br><span class="line">import time</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Mysql</span>:</span></span><br><span class="line">    </span><br><span class="line">    <span class="comment">#获取当前时间</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">getCurrentTime</span><span class="params">(<span class="keyword">self</span>)</span></span><span class="symbol">:</span></span><br><span class="line">        <span class="keyword">return</span> time.strftime(<span class="string">'[%Y-%m-%d %H:%M:%S]'</span>,time.localtime(time.time()))</span><br><span class="line">    </span><br><span class="line">    <span class="comment">#数据库初始化</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(<span class="keyword">self</span>)</span></span><span class="symbol">:</span></span><br><span class="line">        <span class="symbol">try:</span></span><br><span class="line">            <span class="keyword">self</span>.db = MySQLdb.connect(<span class="string">'ip'</span>,<span class="string">'username'</span>,<span class="string">'password'</span>,<span class="string">'db_name'</span>)</span><br><span class="line">            <span class="keyword">self</span>.cur = <span class="keyword">self</span>.db.cursor()</span><br><span class="line">        except MySQLdb.Error,<span class="symbol">e:</span></span><br><span class="line">             print <span class="keyword">self</span>.getCurrentTime(),<span class="string">"连接数据库错误，原因%d: %s"</span> % (e.args[<span class="number">0</span>], e.args[<span class="number">1</span>])</span><br><span class="line"></span><br><span class="line">    <span class="comment">#插入数据</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">insertData</span><span class="params">(<span class="keyword">self</span>, table, my_dict)</span></span><span class="symbol">:</span></span><br><span class="line">         <span class="symbol">try:</span></span><br><span class="line">             <span class="keyword">self</span>.db.set_character_set(<span class="string">'utf8'</span>)</span><br><span class="line">             cols = <span class="string">', '</span>.join(my_dict.keys())</span><br><span class="line">             values = <span class="string">'"," '</span>.join(my_dict.values())</span><br><span class="line">             sql = <span class="string">"INSERT INTO %s (%s) VALUES (%s)"</span> % (table, cols, <span class="string">'"'</span>+values+<span class="string">'"'</span>)</span><br><span class="line">             <span class="symbol">try:</span></span><br><span class="line">                 result = <span class="keyword">self</span>.cur.execute(sql)</span><br><span class="line">                 insert_id = <span class="keyword">self</span>.db.insert_id()</span><br><span class="line">                 <span class="keyword">self</span>.db.commit()</span><br><span class="line">                 <span class="comment">#判断是否执行成功</span></span><br><span class="line">                 <span class="keyword">if</span> <span class="symbol">result:</span></span><br><span class="line">                     <span class="keyword">return</span> insert_id</span><br><span class="line">                 <span class="symbol">else:</span></span><br><span class="line">                     <span class="keyword">return</span> <span class="number">0</span></span><br><span class="line">             except MySQLdb.Error,<span class="symbol">e:</span></span><br><span class="line">                 <span class="comment">#发生错误时回滚</span></span><br><span class="line">                 <span class="keyword">self</span>.db.rollback()</span><br><span class="line">                 <span class="comment">#主键唯一，无法插入</span></span><br><span class="line">                 <span class="keyword">if</span> <span class="string">"key 'PRIMARY'"</span> <span class="keyword">in</span> e.args[<span class="number">1</span>]<span class="symbol">:</span></span><br><span class="line">                     print <span class="keyword">self</span>.getCurrentTime(),<span class="string">"数据已存在，未插入数据"</span></span><br><span class="line">                 <span class="symbol">else:</span></span><br><span class="line">                     print <span class="keyword">self</span>.getCurrentTime(),<span class="string">"插入数据失败，原因 %d: %s"</span> % (e.args[<span class="number">0</span>], e.args[<span class="number">1</span>])</span><br><span class="line">         except MySQLdb.Error,<span class="symbol">e:</span></span><br><span class="line">             print <span class="keyword">self</span>.getCurrentTime(),<span class="string">"数据库错误，原因%d: %s"</span> % (e.args[<span class="number">0</span>], e.args[<span class="number">1</span>])</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>数据库建表SQL如下：</p>
                  <figure class="highlight sql">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="keyword">CREATE</span> <span class="keyword">TABLE</span> <span class="keyword">IF</span> <span class="keyword">NOT</span> <span class="keyword">EXISTS</span> <span class="string">`iask_answers`</span> (</span><br><span class="line">  <span class="string">`id`</span> <span class="built_in">int</span>(<span class="number">11</span>) <span class="keyword">NOT</span> <span class="literal">NULL</span> AUTO_INCREMENT <span class="keyword">COMMENT</span> <span class="string">'自增ID'</span>,</span><br><span class="line">  <span class="string">`text`</span> <span class="built_in">text</span> <span class="keyword">NOT</span> <span class="literal">NULL</span> <span class="keyword">COMMENT</span> <span class="string">'回答内容'</span>,</span><br><span class="line">  <span class="string">`question_id`</span> <span class="built_in">int</span>(<span class="number">18</span>) <span class="keyword">NOT</span> <span class="literal">NULL</span> <span class="keyword">COMMENT</span> <span class="string">'问题ID'</span>,</span><br><span class="line">  <span class="string">`answerer`</span> <span class="built_in">varchar</span>(<span class="number">255</span>) <span class="keyword">NOT</span> <span class="literal">NULL</span> <span class="keyword">COMMENT</span> <span class="string">'回答者'</span>,</span><br><span class="line">  <span class="string">`date`</span> <span class="built_in">varchar</span>(<span class="number">255</span>) <span class="keyword">NOT</span> <span class="literal">NULL</span> <span class="keyword">COMMENT</span> <span class="string">'回答时间'</span>,</span><br><span class="line">  <span class="string">`is_good`</span> <span class="built_in">int</span>(<span class="number">11</span>) <span class="keyword">NOT</span> <span class="literal">NULL</span> <span class="keyword">COMMENT</span> <span class="string">'是否是最佳答案'</span>,</span><br><span class="line">  PRIMARY <span class="keyword">KEY</span> (<span class="string">`id`</span>)</span><br><span class="line">) <span class="keyword">ENGINE</span>=<span class="keyword">InnoDB</span>  <span class="keyword">DEFAULT</span> <span class="keyword">CHARSET</span>=utf8;</span><br><span class="line"></span><br><span class="line"><span class="keyword">CREATE</span> <span class="keyword">TABLE</span> <span class="keyword">IF</span> <span class="keyword">NOT</span> <span class="keyword">EXISTS</span> <span class="string">`iask_questions`</span> (</span><br><span class="line">  <span class="string">`id`</span> <span class="built_in">int</span>(<span class="number">11</span>) <span class="keyword">NOT</span> <span class="literal">NULL</span> AUTO_INCREMENT <span class="keyword">COMMENT</span> <span class="string">'问题ID'</span>,</span><br><span class="line">  <span class="string">`text`</span> <span class="built_in">text</span> <span class="keyword">NOT</span> <span class="literal">NULL</span> <span class="keyword">COMMENT</span> <span class="string">'问题内容'</span>,</span><br><span class="line">  <span class="string">`questioner`</span> <span class="built_in">varchar</span>(<span class="number">255</span>) <span class="keyword">NOT</span> <span class="literal">NULL</span> <span class="keyword">COMMENT</span> <span class="string">'提问者'</span>,</span><br><span class="line">  <span class="string">`date`</span> <span class="built_in">date</span> <span class="keyword">NOT</span> <span class="literal">NULL</span> <span class="keyword">COMMENT</span> <span class="string">'提问时间'</span>,</span><br><span class="line">  <span class="string">`ans_num`</span> <span class="built_in">int</span>(<span class="number">11</span>) <span class="keyword">NOT</span> <span class="literal">NULL</span> <span class="keyword">COMMENT</span> <span class="string">'回答数量'</span>,</span><br><span class="line">  <span class="string">`url`</span> <span class="built_in">varchar</span>(<span class="number">255</span>) <span class="keyword">NOT</span> <span class="literal">NULL</span> <span class="keyword">COMMENT</span> <span class="string">'问题链接'</span>,</span><br><span class="line">  PRIMARY <span class="keyword">KEY</span> (<span class="string">`id`</span>)</span><br><span class="line">) <span class="keyword">ENGINE</span>=<span class="keyword">InnoDB</span>  <span class="keyword">DEFAULT</span> <span class="keyword">CHARSET</span>=utf8;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>运行的时候执行如下命令即可</p>
                  <figure class="highlight vim">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">nohup <span class="keyword">python</span> spider.<span class="keyword">py</span> &amp;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>代码写的不好，仅供大家学习参考使用，如有问题，欢迎留言交流。</p>
                  <h2 id="运行结果查看"><a href="#运行结果查看" class="headerlink" title="运行结果查看"></a>运行结果查看</h2>
                  <p>我们把PHP文件和log文件放在同一目录下，运行PHP文件，便可以看到如下的内容： <a href="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/09/20150908222744.png" target="_blank" rel="noopener"><img src="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/09/20150908222744.png" alt="20150908222744"></a> 小伙伴们赶快试一下吧。</p>
                  </p>
                </div>
              </div>
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-user"></i>
                  </span>
                  <span class="post-meta-item-text">作者</span>
                  <span><a href="/authors/崔庆才" class="author" itemprop="url" rel="index">崔庆才</a></span>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>
                  <time title="创建时间：2015-09-08 22:24:33" itemprop="dateCreated datePublished" datetime="2015-09-08T22:24:33+08:00">2015-09-08</time>
                </span>
                <span id="/1972.html" class="post-meta-item leancloud_visitors" data-flag-title="Python爬虫实战六之抓取爱问知识人问题并保存至数据库" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="fa fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
                <span class="post-meta-item" title="本文字数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-file-word"></i>
                  </span>
                  <span class="post-meta-item-text">本文字数：</span>
                  <span>17k</span>
                </span>
                <span class="post-meta-item" title="阅读时长">
                  <span class="post-meta-item-icon">
                    <i class="far fa-clock"></i>
                  </span>
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                  <span>16 分钟</span>
                </span>
              </div>
            </article>
            <article itemscope itemtype="http://schema.org/Article" class="post-block index" lang="zh-CN">
              <link itemprop="mainEntityOfPage" href="https://cuiqingcai.com/1981.html">
              <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
                <meta itemprop="image" content="/images/avatar.png">
                <meta itemprop="name" content="崔庆才">
                <meta itemprop="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
              </span>
              <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
                <meta itemprop="name" content="静觅">
              </span>
              <header class="post-header">
                <h2 class="post-title" itemprop="name headline">
                  <a class="label"> Other <i class="label-arrow"></i>
                  </a>
                  <a href="/1981.html" class="post-title-link" itemprop="url">Ubuntu Linux下定时监测MySQL进程终止时自动重启的方法</a>
                </h2>
              </header>
              <div class="post-body" itemprop="articleBody">
                <div class="thumb">
                  <img itemprop="contentUrl" class="random">
                </div>
                <div class="excerpt">
                  <p>
                  <h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2>
                  <p>最近发现MySQL服务隔三差五就会挂掉，导致我的网站和爬虫都无法正常运作。自己的网站是基于MySQL，在做爬虫存取一些资料的时候也是基于MySQL，数据量一大了，MySQL它就有点受不了了，时不时会崩掉，虽然我自己有网站监控和邮件通知，但是好多时候还是需要我来手动连接我的服务器重新启动一下我的MySQL，这样简直太不友好了，所以，我就觉定自己写个脚本，定时监控它，如果发现它挂掉了就重启它。 好了，闲言碎语不多讲，开始我们的配置之旅。 运行环境：<strong>Ubuntu Linux 14.04</strong></p>
                  <h2 id="编写Shell脚本"><a href="#编写Shell脚本" class="headerlink" title="编写Shell脚本"></a>编写Shell脚本</h2>
                  <p>首先，我们要编写一个shell脚本，脚本主要执行的逻辑如下： 显示mysqld进程状态，如果判断进程未在运行，那么输出日志到文件，然后启动mysql服务，如果进程在运行，那么不执行任何操作，可以选择性输出监测结果。 可能大家对于shell脚本比较陌生，在这里推荐官方的shell脚本文档来参考一下 <a href="http://wiki.ubuntu.org.cn/Shell%E7%BC%96%E7%A8%8B%E5%9F%BA%E7%A1%80" target="_blank" rel="noopener">Ubuntu Shell 编程基础</a> shell脚本的后缀为sh，在任何位置新建一个脚本文件，我选择在 /etc/mysql 目录下新建一个 listen.sh 文件。 执行如下命令：</p>
                  <figure class="highlight vim">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="keyword">cd</span> /etc/mysql</span><br><span class="line">touch listen.<span class="keyword">sh</span></span><br><span class="line"><span class="keyword">vi</span> listen.<span class="keyword">sh</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>进入到vi中，我们添加如下脚本内容：</p>
                  <figure class="highlight bash">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="meta">#!/bin/bash</span></span><br><span class="line">pgrep mysqld &amp;&gt; /dev/null</span><br><span class="line"><span class="keyword">if</span> [ $? -gt 0 ]</span><br><span class="line"><span class="keyword">then</span></span><br><span class="line"><span class="built_in">echo</span> <span class="string">"`date` mysql is stop"</span></span><br><span class="line">service mysql start</span><br><span class="line"><span class="keyword">else</span></span><br><span class="line"><span class="built_in">echo</span> <span class="string">"`date` mysql running"</span></span><br><span class="line"><span class="keyword">fi</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>其中 pgrep mysqld 是监测mysqld服务的运行状态，&amp;&gt; /dev/null 是将其结果输出到空文件，也就是不保存输出信息 $? 是拿到上一条命令的运行结果，-gt 0 是判断是否大于0，后面则是输出时间到日志文件，然后启动mysql，否则不启动mysql 保存好了，那么我们执行如下的命令，来测试一下。 <a href="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/08/20150816164552.jpg" target="_blank" rel="noopener"><img src="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/08/20150816164552.jpg" alt="20150816164552"></a> 贴心的命令文字版本：</p>
                  <figure class="highlight elixir">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">root<span class="variable">@iZ28uogb3laZ</span><span class="symbol">:/etc/mysql</span><span class="comment"># vi listen.sh</span></span><br><span class="line">root<span class="variable">@iZ28uogb3laZ</span><span class="symbol">:/etc/mysql</span><span class="comment"># pgrep mysqld</span></span><br><span class="line"><span class="number">3359</span></span><br><span class="line">root<span class="variable">@iZ28uogb3laZ</span><span class="symbol">:/etc/mysql</span><span class="comment"># chmod 777 listen.sh</span></span><br><span class="line">root<span class="variable">@iZ28uogb3laZ</span><span class="symbol">:/etc/mysql</span><span class="comment"># ./listen.sh</span></span><br><span class="line">Sun Aug <span class="number">16 16</span><span class="symbol">:</span><span class="number">44:58</span> CST <span class="number">2015</span> mysql running</span><br><span class="line">root<span class="variable">@iZ28uogb3laZ</span><span class="symbol">:/etc/mysql</span><span class="comment"># sudo service mysql stop</span></span><br><span class="line">mysql stop/waiting</span><br><span class="line">root<span class="variable">@iZ28uogb3laZ</span><span class="symbol">:/etc/mysql</span><span class="comment"># ./listen.sh</span></span><br><span class="line">Sun Aug <span class="number">16 16</span><span class="symbol">:</span><span class="number">45:17</span> CST <span class="number">2015</span> mysql is stop</span><br><span class="line">mysql start/running, process <span class="number">4084</span></span><br><span class="line">root<span class="variable">@iZ28uogb3laZ</span><span class="symbol">:/etc/mysql</span><span class="comment"># ./listen.sh</span></span><br><span class="line">Sun Aug <span class="number">16 16</span><span class="symbol">:</span><span class="number">45:24</span> CST <span class="number">2015</span> mysql running</span><br><span class="line">root<span class="variable">@iZ28uogb3laZ</span><span class="symbol">:/etc/mysql</span><span class="comment">#</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>嗯，编辑完了.sh文件之后，我们首先要对其进行授权，增加可执行的权限。</p>
                  <figure class="highlight lsl">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">sudo chmod <span class="number">777</span> <span class="section">listen</span>.sh</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>然后运行脚本测试一下，显示mysql正在运行。把mysql关掉，运行脚本，便会检测到mysql已关闭，然后重新启动了mysql，再次运行，便会发现mysql正常运行了。 <strong>注：这里我比较纳闷shell脚本中pgrep mysqld的返回结果是什么。为什么它大于0便代表mysql服务挂掉了呢？感觉逻辑有点是相反的，不过实测可用有效。如果大家明白为什么，非常希望您可以给我一个解释。</strong></p>
                  <h2 id="修改日志输出"><a href="#修改日志输出" class="headerlink" title="修改日志输出"></a>修改日志输出</h2>
                  <p>好，接下来我们把输出的内容保存到日志里。修改脚本文件如下</p>
                  <figure class="highlight bash">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="meta">#!/bin/bash</span></span><br><span class="line">pgrep mysqld &amp;&gt; /dev/null</span><br><span class="line"><span class="keyword">if</span> [ $? -gt 0 ]</span><br><span class="line"><span class="keyword">then</span></span><br><span class="line"><span class="built_in">echo</span> <span class="string">"`date` mysql is stop"</span> &gt;&gt; /var/<span class="built_in">log</span>/mysql_listen.log</span><br><span class="line">service mysql start</span><br><span class="line"><span class="keyword">else</span></span><br><span class="line"><span class="built_in">echo</span> <span class="string">"`date` mysql running"</span> &gt;&gt; /var/<span class="built_in">log</span>/mysql_listen.log</span><br><span class="line"><span class="keyword">fi</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>这样，每执行一次脚本，输出结果都会被保存到 /var/log/mysql_listen.log 中了。</p>
                  <h2 id="添加定时任务"><a href="#添加定时任务" class="headerlink" title="添加定时任务"></a>添加定时任务</h2>
                  <p>好了，脚本可以顺利执行了，那么我们就需要定时调用一下这个脚本来运行了，我们需要用到 cron。 首先我们需要编辑一下corn调度表格，命令如下：</p>
                  <figure class="highlight ebnf">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="attribute">crontab -e</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>如果你是第一次编辑这个，他会让你选择文件打开方式，随便选一个数字就好了。 比如我们用GNU打开的，我们就在它的最后一行添加下面的一句话即可。 <a href="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/08/20150816165506.jpg" target="_blank" rel="noopener"><img src="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/08/20150816165506.jpg" alt="20150816165506"></a>、 文字版本：</p>
                  <figure class="highlight awk">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">*<span class="regexp">/5 * * * * /</span>etc<span class="regexp">/mysql/my</span>sql_listen.sh</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>/5代表五分钟执行一次，后面的四个点依次代表了，小时，日，月，星期。如果想要时间长一些，比如一小时调度一次，那就设置一下后面第一个*就好了。 好，保存一下，重启cron服务。</p>
                  <figure class="highlight ebnf">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="attribute">service cron restart</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>嗯，调度任务已经添加进去了，这样，每五分钟系统就会调用一下刚才写的那个脚本。 过一段时间，我们来看一下运行效果，嗯，监控跑的很顺利呐。 <a href="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/08/20150816165858.jpg" target="_blank" rel="noopener"><img src="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/08/20150816165858.jpg" alt="20150816165858"></a> 文字版本：</p>
                  <figure class="highlight angelscript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">Sun Aug <span class="number">16</span> <span class="number">15</span>:<span class="number">39</span>:<span class="number">12</span> CST <span class="number">2015</span> mysql running</span><br><span class="line">Sun Aug <span class="number">16</span> <span class="number">15</span>:<span class="number">40</span>:<span class="number">01</span> CST <span class="number">2015</span> mysql running</span><br><span class="line">Sun Aug <span class="number">16</span> <span class="number">15</span>:<span class="number">45</span>:<span class="number">02</span> CST <span class="number">2015</span> mysql running</span><br><span class="line">Sun Aug <span class="number">16</span> <span class="number">15</span>:<span class="number">50</span>:<span class="number">01</span> CST <span class="number">2015</span> mysql running</span><br><span class="line">Sun Aug <span class="number">16</span> <span class="number">15</span>:<span class="number">55</span>:<span class="number">01</span> CST <span class="number">2015</span> mysql running</span><br><span class="line">Sun Aug <span class="number">16</span> <span class="number">16</span>:<span class="number">00</span>:<span class="number">01</span> CST <span class="number">2015</span> mysql running</span><br><span class="line">Sun Aug <span class="number">16</span> <span class="number">16</span>:<span class="number">05</span>:<span class="number">01</span> CST <span class="number">2015</span> mysql running</span><br><span class="line">Sun Aug <span class="number">16</span> <span class="number">16</span>:<span class="number">10</span>:<span class="number">01</span> CST <span class="number">2015</span> mysql running</span><br><span class="line">Sun Aug <span class="number">16</span> <span class="number">16</span>:<span class="number">15</span>:<span class="number">01</span> CST <span class="number">2015</span> mysql running</span><br><span class="line">Sun Aug <span class="number">16</span> <span class="number">16</span>:<span class="number">20</span>:<span class="number">01</span> CST <span class="number">2015</span> mysql running</span><br><span class="line">Sun Aug <span class="number">16</span> <span class="number">16</span>:<span class="number">25</span>:<span class="number">01</span> CST <span class="number">2015</span> mysql running</span><br><span class="line">Sun Aug <span class="number">16</span> <span class="number">16</span>:<span class="number">30</span>:<span class="number">01</span> CST <span class="number">2015</span> mysql running</span><br><span class="line">Sun Aug <span class="number">16</span> <span class="number">16</span>:<span class="number">35</span>:<span class="number">01</span> CST <span class="number">2015</span> mysql running</span><br><span class="line">Sun Aug <span class="number">16</span> <span class="number">16</span>:<span class="number">40</span>:<span class="number">01</span> CST <span class="number">2015</span> mysql running</span><br><span class="line">Sun Aug <span class="number">16</span> <span class="number">16</span>:<span class="number">51</span>:<span class="number">04</span> CST <span class="number">2015</span> mysql running</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>哈哈，是不是五分钟监测了一次呢？大功告成。</p>
                  <h2 id="后记"><a href="#后记" class="headerlink" title="后记"></a>后记</h2>
                  <p>这样，我们就实现了五分钟定时检测MySQL进程服务，妈妈再也不用担心我的网站会宕掉啦。 如有问题，欢迎留言交流，谢谢啦。</p>
                  </p>
                </div>
              </div>
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-user"></i>
                  </span>
                  <span class="post-meta-item-text">作者</span>
                  <span><a href="/authors/崔庆才" class="author" itemprop="url" rel="index">崔庆才</a></span>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>
                  <time title="创建时间：2015-08-16 17:06:30" itemprop="dateCreated datePublished" datetime="2015-08-16T17:06:30+08:00">2015-08-16</time>
                </span>
                <span id="/1981.html" class="post-meta-item leancloud_visitors" data-flag-title="Ubuntu Linux下定时监测MySQL进程终止时自动重启的方法" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="fa fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
                <span class="post-meta-item" title="本文字数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-file-word"></i>
                  </span>
                  <span class="post-meta-item-text">本文字数：</span>
                  <span>2.9k</span>
                </span>
                <span class="post-meta-item" title="阅读时长">
                  <span class="post-meta-item-icon">
                    <i class="far fa-clock"></i>
                  </span>
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                  <span>3 分钟</span>
                </span>
              </div>
            </article>
            <article itemscope itemtype="http://schema.org/Article" class="post-block index" lang="zh-CN">
              <link itemprop="mainEntityOfPage" href="https://cuiqingcai.com/1934.html">
              <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
                <meta itemprop="image" content="/images/avatar.png">
                <meta itemprop="name" content="崔庆才">
                <meta itemprop="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
              </span>
              <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
                <meta itemprop="name" content="静觅">
              </span>
              <header class="post-header">
                <h2 class="post-title" itemprop="name headline">
                  <a class="label"> C/C++ <i class="label-arrow"></i>
                  </a>
                  <a href="/1934.html" class="post-title-link" itemprop="url">C语言小知识点练习总结</a>
                </h2>
              </header>
              <div class="post-body" itemprop="articleBody">
                <div class="thumb">
                  <img itemprop="contentUrl" class="random">
                </div>
                <div class="excerpt">
                  <p>
                  <p>最近在准备C语言的上级考试，之前对C接触不多，在练习过程中把一些小知识点记录下来。</p>
                  <h2 id="1-字符串的截取"><a href="#1-字符串的截取" class="headerlink" title="1.字符串的截取"></a>1.字符串的截取</h2>
                  <p>利用strncpy函数，传入三个参数，分别为目标字符串，起始位置，长度。 例如将日期字符串转化为数字，如20120112</p>
                  <figure class="highlight cpp">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;string.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdlib.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">char</span> date1[<span class="number">20</span>],date2[<span class="number">20</span>];</span><br><span class="line">    <span class="built_in">scanf</span>(<span class="string">"%s"</span>,&amp;date1);</span><br><span class="line">    <span class="built_in">scanf</span>(<span class="string">"%s"</span>,&amp;date2);</span><br><span class="line">    <span class="keyword">char</span> temp[<span class="number">4</span>];</span><br><span class="line">    <span class="keyword">int</span> year1 = atoi(<span class="built_in">strncpy</span>(temp,date1,<span class="number">4</span>));</span><br><span class="line">    <span class="keyword">int</span> year2 = atoi(<span class="built_in">strncpy</span>(temp,date2,<span class="number">4</span>));</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"year1:%d\n"</span>,year1);</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"year2:%d\n"</span>,year2);</span><br><span class="line">    <span class="keyword">char</span> temp2[<span class="number">2</span>];</span><br><span class="line">    <span class="keyword">int</span> month1 = atoi(<span class="built_in">strncpy</span>(temp2,date1+<span class="number">4</span>,<span class="number">2</span>));</span><br><span class="line">    <span class="keyword">int</span> month2 = atoi(<span class="built_in">strncpy</span>(temp2,date2+<span class="number">4</span>,<span class="number">2</span>));</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"month1:%d\n"</span>,month1);</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"month2:%d\n"</span>,month2);</span><br><span class="line">    <span class="keyword">int</span> day1 = atoi(<span class="built_in">strncpy</span>(temp2,date1+<span class="number">6</span>,<span class="number">2</span>));</span><br><span class="line">    <span class="keyword">int</span> day2 = atoi(<span class="built_in">strncpy</span>(temp2,date2+<span class="number">6</span>,<span class="number">2</span>));</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"day1:%d\n"</span>,day1);</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"day2:%d\n"</span>,day2);</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>以上便实现了输入一个日期然后对其进行分割的操作。</p>
                  <h2 id="2-二维数组的动态声明"><a href="#2-二维数组的动态声明" class="headerlink" title="2.二维数组的动态声明"></a>2.二维数组的动态声明</h2>
                  <p>利用malloc可以实现数组的动态声明</p>
                  <figure class="highlight angelscript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="built_in">int</span> **a;</span><br><span class="line">    a = (<span class="built_in">int</span> **)malloc(<span class="number">2</span>*sizeof(<span class="built_in">int</span> *));</span><br><span class="line">    <span class="built_in">int</span> i,j;</span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; <span class="number">2</span>; i ++) &#123;</span><br><span class="line">        a[i] = (<span class="built_in">int</span> *)malloc(<span class="number">3</span>*sizeof(<span class="built_in">int</span>));</span><br><span class="line">        <span class="keyword">for</span> (j = <span class="number">0</span>; j &lt; <span class="number">3</span>; j++) &#123;</span><br><span class="line">            scanf(<span class="string">"%d"</span>,&amp;a[i][j]);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>以上便实现了动态数组的分配，利用scanf为数组赋值</p>
                  <h2 id="3-二维数组的声明和初始化"><a href="#3-二维数组的声明和初始化" class="headerlink" title="3.二维数组的声明和初始化"></a>3.二维数组的声明和初始化</h2>
                  <p>头文件</p>
                  <figure class="highlight autoit">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;memory.h&gt;</span></span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>初始化和测试</p>
                  <figure class="highlight matlab">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">int result[<span class="number">2</span>][<span class="number">2</span>];</span><br><span class="line">    <span class="keyword">for</span> (<span class="built_in">i</span> = <span class="number">0</span>; <span class="built_in">i</span> &lt; <span class="number">2</span>; <span class="built_in">i</span> ++) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="built_in">j</span> = <span class="number">0</span>; <span class="built_in">j</span> &lt; <span class="number">2</span>; <span class="built_in">j</span>++) &#123;</span><br><span class="line">            printf(<span class="string">"%d "</span>,result[<span class="built_in">i</span>][<span class="built_in">j</span>]);</span><br><span class="line">        &#125;</span><br><span class="line">        printf(<span class="string">"\n"</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    memset(result,<span class="number">0</span>,sizeof(int)*<span class="number">4</span>);</span><br><span class="line">    <span class="keyword">for</span> (<span class="built_in">i</span> = <span class="number">0</span>; <span class="built_in">i</span> &lt; <span class="number">2</span>; <span class="built_in">i</span> ++) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="built_in">j</span> = <span class="number">0</span>; <span class="built_in">j</span> &lt; <span class="number">2</span>; <span class="built_in">j</span>++) &#123;</span><br><span class="line">            printf(<span class="string">"%d "</span>,result[<span class="built_in">i</span>][<span class="built_in">j</span>]);</span><br><span class="line">        &#125;</span><br><span class="line">        printf(<span class="string">"\n"</span>);</span><br><span class="line">    &#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>结果</p>
                  <figure class="highlight basic">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="symbol">4196944 </span><span class="number">0</span> </span><br><span class="line"><span class="symbol">4195696 </span><span class="number">0</span> </span><br><span class="line"><span class="symbol">0 </span><span class="number">0</span> </span><br><span class="line"><span class="symbol">0 </span><span class="number">0</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>上述是数组的非动态声明</p>
                  <h2 id="4-快速排序"><a href="#4-快速排序" class="headerlink" title="4.快速排序"></a>4.快速排序</h2>
                  <p>假设要排序的数组是A[1]……A[N]，首先任意选取一个数据（通常选用第一个数据）作为关键数据，然后将所有比它的数都放到它前面，所有比它大的数都放到它后面，这个过程称为一趟快速排序。一趟快速排序的算法是： 1）设置两个变量I、J，排序开始的时候 I=0，J=N-1； 2）以第一个数组元素作为关键数据，赋值给X，即X=A[0]； 3）从J开始向前搜索，即由后开始向前搜索，找到第一个小于X的值，两者交换； 4）从I开始向后搜索，即由前开始向后搜索，找到第一个大于X的值，两者交换； 5）重复第3、4步，直到I=J； 例如：待排序的数组A的值分别是：（初始关键数据X：=49） A[0] A[1] A[2] A[3] A[4] A[5] A[6] 49 38 65 97 76 13 27 进行第一次交换后： 27 38 65 97 76 13 49 ( 按照算法的第三步从后面开始找 ） 进行第二次交换后： 27 38 49 97 76 13 65 ( 按照算法的第四步从前面开始找&gt;X的值，65&gt;49,两者交换，此时I=3 ) 进行第三次交换后： 27 38 13 97 76 49 65 ( 按照算法的第五步将又一次执行算法的第三步从后开始找） 进行第四次交换后： 27 38 13 49 76 97 65 ( 按照算法的第四步从前面开始找大于X的值，97&gt;49,两者交换，此时J=4 ) 此时再执行第三不的时候就发现I=J，从而结束一躺快速排序，那么经过一躺快速排序之后： 27 38 13 49 76 97 65 即所有大于49的数全部在49的后面，所有小于49的数全部在49的前面。</p>
                  <figure class="highlight angelscript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">#include &lt;stdio.h&gt;</span><br><span class="line"></span><br><span class="line"><span class="built_in">void</span> quiksort(<span class="built_in">int</span> a[],<span class="built_in">int</span> low,<span class="built_in">int</span> high)</span><br><span class="line">&#123;</span><br><span class="line">    <span class="built_in">int</span> i = low;</span><br><span class="line">    <span class="built_in">int</span> j = high;  </span><br><span class="line">    <span class="built_in">int</span> temp = a[i]; </span><br><span class="line">  </span><br><span class="line">    <span class="keyword">if</span>( low &lt; high)</span><br><span class="line">    &#123;          </span><br><span class="line">        <span class="keyword">while</span>(i &lt; j) </span><br><span class="line">        &#123;</span><br><span class="line">            <span class="keyword">while</span>((a[j] &gt;= temp) &amp;&amp; (i &lt; j))</span><br><span class="line">            &#123; </span><br><span class="line">                j--; </span><br><span class="line">            &#125;</span><br><span class="line">            a[i] = a[j];</span><br><span class="line">            <span class="keyword">while</span>((a[i] &lt;= temp) &amp;&amp; (i &lt; j))</span><br><span class="line">            &#123;</span><br><span class="line">                i++; </span><br><span class="line">            &#125;  </span><br><span class="line">            a[j]= a[i];</span><br><span class="line">        &#125;</span><br><span class="line">        a[i] = temp;</span><br><span class="line">        quiksort(a,low,i<span class="number">-1</span>);</span><br><span class="line">        quiksort(a,j+<span class="number">1</span>,high);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"> </span><br><span class="line"><span class="built_in">int</span> main()</span><br><span class="line">&#123;</span><br><span class="line">    <span class="built_in">int</span> arr[<span class="number">5</span>] = &#123;<span class="number">23</span>,<span class="number">1</span>,<span class="number">21</span>,<span class="number">4</span>,<span class="number">19</span>&#125;;</span><br><span class="line">    quiksort(arr,<span class="number">0</span>,<span class="number">4</span>);</span><br><span class="line">    <span class="built_in">int</span> i;</span><br><span class="line">    <span class="keyword">for</span>(i=<span class="number">0</span>;i&lt;<span class="number">5</span>;i++)</span><br><span class="line">    &#123;</span><br><span class="line">        printf(<span class="string">"%d "</span>,arr[i]);</span><br><span class="line">    &#125;</span><br><span class="line">    printf(<span class="string">"\n"</span>);</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>快速排序代码如上</p>
                  <h2 id="5-字符串拷贝"><a href="#5-字符串拷贝" class="headerlink" title="5.字符串拷贝"></a>5.字符串拷贝</h2>
                  <p>小例子如下</p>
                  <figure class="highlight cpp">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;string.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdlib.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">	<span class="keyword">char</span> str[<span class="number">20</span>] = <span class="string">"hello"</span>;</span><br><span class="line">	<span class="keyword">char</span> *a = <span class="string">"world"</span>;</span><br><span class="line">	<span class="built_in">strcpy</span>(str,a);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">"%s"</span>,str);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">"\n"</span>);</span><br><span class="line">	system(<span class="string">"pause"</span>);</span><br><span class="line">	<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>运行结果：world，即把后者完全覆盖前者。</p>
                  <figure class="highlight cpp">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;string.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdlib.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">	<span class="keyword">char</span> *str = <span class="keyword">new</span> <span class="keyword">char</span>[<span class="number">6</span>];</span><br><span class="line">	<span class="keyword">char</span> *a = <span class="string">"world"</span>;</span><br><span class="line">	<span class="built_in">strcpy</span>(str,a);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">"%s"</span>, str);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">"\n"</span>);</span><br><span class="line">	system(<span class="string">"pause"</span>);</span><br><span class="line">	<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>运行结果一致 某一长度的字符串截取</p>
                  <figure class="highlight cpp">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;string.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdlib.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">	<span class="keyword">char</span> *str = <span class="keyword">new</span> <span class="keyword">char</span>[<span class="number">6</span>];</span><br><span class="line">	<span class="keyword">char</span> *a = <span class="string">"world"</span>;</span><br><span class="line">	<span class="built_in">strncpy</span>(str,a+<span class="number">1</span>,<span class="number">5</span>);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">"%s"</span>, str);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">"\n"</span>);</span><br><span class="line">	system(<span class="string">"pause"</span>);</span><br><span class="line">	<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>运行结果：orld</p>
                  <h2 id="6-字符串的拼接"><a href="#6-字符串的拼接" class="headerlink" title="6.字符串的拼接"></a>6.字符串的拼接</h2>
                  <p>小例子如下</p>
                  <figure class="highlight cpp">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;string.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdlib.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">	<span class="keyword">char</span> str[<span class="number">20</span>] = <span class="string">"hello "</span>;</span><br><span class="line">	<span class="keyword">char</span> *a = <span class="string">"world"</span>;</span><br><span class="line">	<span class="keyword">char</span> *x = <span class="built_in">strcat</span>(str,a);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">"%s\n"</span>, x);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">"%s\n"</span>, x);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">"\n"</span>);</span><br><span class="line">	system(<span class="string">"pause"</span>);</span><br><span class="line">	<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>运行结果： hello world hello world 此函数既返回结果，又将目标字符串赋值</p>
                  <h2 id="7-字符串查找匹配"><a href="#7-字符串查找匹配" class="headerlink" title="7.字符串查找匹配"></a>7.字符串查找匹配</h2>
                  <p>例子如下</p>
                  <figure class="highlight cpp">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;string.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdlib.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">	<span class="keyword">char</span> str[<span class="number">20</span>] = <span class="string">"hello "</span>;</span><br><span class="line">	<span class="keyword">char</span> *x = <span class="built_in">strchr</span>(str,<span class="string">'e'</span>);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">"%d\n"</span>, x - str);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">"%s\n"</span>,x);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">"\n"</span>);</span><br><span class="line">	system(<span class="string">"pause"</span>);</span><br><span class="line">	<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>运行结果： 1 ello</p>
                  <h2 id="8-字符串比较"><a href="#8-字符串比较" class="headerlink" title="8.字符串比较"></a>8.字符串比较</h2>
                  <p>例子如下</p>
                  <figure class="highlight cpp">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;string.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdlib.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">	<span class="keyword">char</span> str[<span class="number">20</span>] = <span class="string">"hello "</span>;</span><br><span class="line">	<span class="keyword">char</span> str2[<span class="number">20</span>] = <span class="string">"hello2"</span>;</span><br><span class="line">	<span class="keyword">int</span> x = <span class="built_in">strcmp</span>(str, str2);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">"%d\n"</span>,x);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">"\n"</span>);</span><br><span class="line">	system(<span class="string">"pause"</span>);</span><br><span class="line">	<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>运行结果-1 忽略大小写</p>
                  <figure class="highlight cpp">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;string.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdlib.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line">	<span class="keyword">char</span> str[<span class="number">20</span>] = <span class="string">"hello"</span>;</span><br><span class="line">	<span class="keyword">char</span> str2[<span class="number">20</span>] = <span class="string">"Hello"</span>;</span><br><span class="line">	<span class="keyword">int</span> x = stricmp(str, str2);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">"%d\n"</span>,x);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">"\n"</span>);</span><br><span class="line">	system(<span class="string">"pause"</span>);</span><br><span class="line">	<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>运行结果0</p>
                  <h2 id="9-字符串分割"><a href="#9-字符串分割" class="headerlink" title="9.字符串分割"></a>9.字符串分割</h2>
                  <p>示例如下</p>
                  <figure class="highlight cpp">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;string.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdlib.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">      <span class="keyword">char</span> test1[] = <span class="string">"feng,ke,wei"</span>;  </span><br><span class="line">	  <span class="keyword">char</span> x[<span class="number">3</span>][<span class="number">30</span>];</span><br><span class="line">      <span class="keyword">char</span> *p;  </span><br><span class="line">      p = strtok(test1, <span class="string">","</span>);</span><br><span class="line">	  <span class="keyword">int</span> count = <span class="number">0</span>;</span><br><span class="line">      <span class="keyword">while</span> (p) &#123;   </span><br><span class="line">		<span class="built_in">printf</span>(<span class="string">"%s\n"</span>, p);   </span><br><span class="line">		<span class="built_in">strcpy</span>(x[count],p);</span><br><span class="line">		count++;</span><br><span class="line">		p = strtok(<span class="literal">NULL</span>, <span class="string">","</span>);     </span><br><span class="line">      &#125;    </span><br><span class="line">	  <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i&lt;count; i ++) &#123;</span><br><span class="line">		<span class="built_in">printf</span>(<span class="string">"%s "</span>, x[i]);</span><br><span class="line">	  &#125;</span><br><span class="line">	  system(<span class="string">"pause"</span>);</span><br><span class="line">      <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"> &#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>运行结果 feng ke wei feng ke wei</p>
                  <h2 id="10-格式化输出几位小数"><a href="#10-格式化输出几位小数" class="headerlink" title="10.格式化输出几位小数"></a>10.格式化输出几位小数</h2>
                  <p>例如</p>
                  <figure class="highlight cpp">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="built_in">printf</span>(<span class="string">"%.5f"</span>,<span class="number">18.223</span>);</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>则是输出5位小数 又如</p>
                  <figure class="highlight perl">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="keyword">printf</span>(<span class="string">"%5.1f"</span>,<span class="number">1.2345</span>);</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>则是控制总位数为5，小数点后为1位，不够的在前面补空格</p>
                  </p>
                </div>
              </div>
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-user"></i>
                  </span>
                  <span class="post-meta-item-text">作者</span>
                  <span><a href="/authors/崔庆才" class="author" itemprop="url" rel="index">崔庆才</a></span>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>
                  <time title="创建时间：2015-07-18 21:52:01" itemprop="dateCreated datePublished" datetime="2015-07-18T21:52:01+08:00">2015-07-18</time>
                </span>
                <span id="/1934.html" class="post-meta-item leancloud_visitors" data-flag-title="C语言小知识点练习总结" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="fa fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
                <span class="post-meta-item" title="本文字数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-file-word"></i>
                  </span>
                  <span class="post-meta-item-text">本文字数：</span>
                  <span>4.8k</span>
                </span>
                <span class="post-meta-item" title="阅读时长">
                  <span class="post-meta-item-icon">
                    <i class="far fa-clock"></i>
                  </span>
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                  <span>4 分钟</span>
                </span>
              </div>
            </article>
            <article itemscope itemtype="http://schema.org/Article" class="post-block index" lang="zh-CN">
              <link itemprop="mainEntityOfPage" href="https://cuiqingcai.com/1922.html">
              <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
                <meta itemprop="image" content="/images/avatar.png">
                <meta itemprop="name" content="崔庆才">
                <meta itemprop="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
              </span>
              <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
                <meta itemprop="name" content="静觅">
              </span>
              <header class="post-header">
                <h2 class="post-title" itemprop="name headline">
                  <a class="label"> C/C++ <i class="label-arrow"></i>
                  </a>
                  <a href="/1922.html" class="post-title-link" itemprop="url">Winpcap网络编程六之两台主机通过中间主机通信</a>
                </h2>
              </header>
              <div class="post-body" itemprop="articleBody">
                <div class="thumb">
                  <img itemprop="contentUrl" class="random">
                </div>
                <div class="excerpt">
                  <p>
                  <h2 id="本节任务"><a href="#本节任务" class="headerlink" title="本节任务"></a>本节任务</h2>
                  <p>本次我们需要完成的任务是 完成两台主机通过中间主机的数据通信（网络层）</p>
                  <ul>
                    <li>增加基于IP地址的转发功能</li>
                    <li>增加网络层封装</li>
                  </ul>
                  <p>其实最主要的就是基于IP地址的转发功能，网络层的封装其实我们在初级功能中就已经做好了。</p>
                  <h2 id="原理"><a href="#原理" class="headerlink" title="原理"></a>原理</h2>
                  <p>首先，实验的思路是A通过中间主机B向C发送数据。那么B则作为一个路由器，B要监听两个网卡，一个网卡发来的数据通过另一个网卡发出去。 示意图如下： A————-&gt;B1===B2——————&gt;C 从图上可以看出，B主机的两个网卡数据互通，A和B1则处于一个局域网内，B2和C处于另一个局域网内。 就比如这样，现在室友A在用有线上网，我的电脑B也在用有线上网，我们的有线处在同一局域网，我的电脑B同时散着一个无线网，我的手机C又连接到了这个无线上。 那么要实现A到C的数据传送，即模拟室友A要发送数据到我的手机C，那么流程则是这样的： 室友A在有线局域网发送数据到我的网卡B1，B1将数据通过网卡B2转发到无线局域网，通过无线局域网到达我的手机C。 A的发送要构建一个帧，目的MAC地址为B1,目的IP为C。B则要开启两个网卡，B1监听接收数据，B2网卡则要用ARP协议扫描所在无线局域网内的IP和MAC,B获取到了A发来的帧之后，解析它的IP地址和MAC地址，匹配刚才扫描得到的IP和MAC对应表，将源MAC换成B2网卡MAC，目的MAC换成C的MAC，IP不变，数据data不变。构建新帧之后发送出去。 好啦，思路大体就是这样。</p>
                  <h2 id="实战"><a href="#实战" class="headerlink" title="实战"></a>实战</h2>
                  <p>需要三个程序，一个是发送，一个路由，一个接收。所以一共三个程序要同时运行起来执行。 以上是我的大体思路，如有错误，还请指正。现已用代码实现完毕。 代码暂不公开，只提供部分重点代码解析：</p>
                  <h3 id="一、发送端"><a href="#一、发送端" class="headerlink" title="一、发送端"></a>一、发送端</h3>
                  <p>其实发送端和初级功能的发送差不多 个人编写的交互流程如下：</p>
                  <figure class="highlight angelscript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">IP地址:<span class="number">121.250</span><span class="number">.216</span><span class="number">.221</span>   MAC地址:<span class="number">3</span>c970e4b56d6con:<span class="number">127</span></span><br><span class="line"></span><br><span class="line">-------------------------------------------</span><br><span class="line">IP地址:<span class="number">121.250</span><span class="number">.216</span><span class="number">.227</span>   MAC地址:<span class="number">089e01</span>b948f4con:<span class="number">128</span></span><br><span class="line"></span><br><span class="line">-------------------------------------------</span><br><span class="line">IP地址:<span class="number">121.250</span><span class="number">.216</span><span class="number">.228</span>   MAC地址:<span class="number">10</span>bf48705aeecon:<span class="number">129</span></span><br><span class="line"></span><br><span class="line">获取MAC地址完毕,请输入你要发送对方的IP地址:</span><br><span class="line"><span class="number">192.168</span><span class="number">.1</span><span class="number">.3</span></span><br><span class="line">请输入你要发送的内容:</span><br><span class="line">im cqc</span><br><span class="line">要发送的内容:im cqc</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>具体代码不再解析，同上一篇初级功能。</p>
                  <h3 id="二、路由端"><a href="#二、路由端" class="headerlink" title="二、路由端"></a>二、路由端</h3>
                  <p>首先要开启两个网卡，声明两个网卡对象和处理器</p>
                  <figure class="highlight cpp">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="keyword">pcap_if_t</span>  *d,*d2;					<span class="comment">//选中的网络适配器</span></span><br><span class="line"><span class="keyword">pcap_t</span> *adhandle,*adhandle2;           <span class="comment">//捕捉实例,是pcap_open返回的对象,adhandle是用来发送数据，adhandle2是用来接收数据</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>一个用来接收一个用来发送，这里定义了adhandle是用来发送，adhandle2是用来接收数据。 那么打开适配器就在main方法中，提前打开两个网卡</p>
                  <figure class="highlight xl">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">int num;</span><br><span class="line">	printf(<span class="string">"请输入你要转发数据的网卡代号:\n"</span>);</span><br><span class="line">	<span class="comment">//让用户选择选择哪个适配器进行转发</span></span><br><span class="line">	scanf_s(<span class="string">"%d"</span>,&amp;num);</span><br><span class="line"></span><br><span class="line">	<span class="comment">//跳转到选中的适配器</span></span><br><span class="line">	<span class="function"><span class="title">for</span>(d=alldevs, i=0; i&lt; num-1 ; d=d-&gt;</span>next, i++);</span><br><span class="line"></span><br><span class="line">	<span class="comment">//运行到此处说明用户的输入是合法的，找到发送数据网卡</span></span><br><span class="line">	<span class="function"><span class="title">if</span>((adhandle = pcap_open(d-&gt;</span><span class="keyword">name</span>,		<span class="comment">//设备名称</span></span><br><span class="line">													<span class="number">65535</span>,       <span class="comment">//存放数据包的内容长度</span></span><br><span class="line">													PCAP_OPENFLAG_PROMISCUOUS,  <span class="comment">//混杂模式</span></span><br><span class="line">													<span class="number">1000</span>,           <span class="comment">//超时时间</span></span><br><span class="line">													NULL,          <span class="comment">//远程验证</span></span><br><span class="line">													errbuf         <span class="comment">//错误缓冲</span></span><br><span class="line">													)) == NULL)&#123;</span><br><span class="line">    <span class="comment">//打开适配器失败,打印错误并释放适配器列表</span></span><br><span class="line">	<span class="function"><span class="title">fprintf</span>(stderr,"\nUnable to open the adapter. %s <span class="keyword">is</span> <span class="built_in">not</span> supported <span class="keyword">by</span> WinPcap\n", d-&gt;</span><span class="keyword">name</span>);</span><br><span class="line">    <span class="comment">// 释放设备列表 </span></span><br><span class="line">    pcap_freealldevs(alldevs);</span><br><span class="line">    return -<span class="number">1</span>;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	int num2;</span><br><span class="line">	printf(<span class="string">"请输入你要接收数据的网卡代号:"</span>);</span><br><span class="line">	<span class="comment">//让用户选择用哪个网卡来收数据</span></span><br><span class="line">	scanf_s(<span class="string">"%d"</span>,&amp;num2);</span><br><span class="line">	<span class="comment">//用户输入的数字超出合理范围</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">	<span class="comment">//跳转到选中的适配器</span></span><br><span class="line">	<span class="function"><span class="title">for</span>(d2=alldevs, i=0; i&lt; num2-1 ; d2=d2-&gt;</span>next, i++);</span><br><span class="line"></span><br><span class="line">	<span class="comment">//运行到此处说明用户的输入是合法的</span></span><br><span class="line">	<span class="function"><span class="title">if</span>((adhandle2 = pcap_open(d2-&gt;</span><span class="keyword">name</span>,		<span class="comment">//设备名称</span></span><br><span class="line">													<span class="number">65535</span>,       <span class="comment">//存放数据包的内容长度</span></span><br><span class="line">													PCAP_OPENFLAG_PROMISCUOUS,  <span class="comment">//混杂模式</span></span><br><span class="line">													<span class="number">1000</span>,           <span class="comment">//超时时间</span></span><br><span class="line">													NULL,          <span class="comment">//远程验证</span></span><br><span class="line">													errbuf         <span class="comment">//错误缓冲</span></span><br><span class="line">													)) == NULL)&#123;</span><br><span class="line">    <span class="comment">//打开适配器失败,打印错误并释放适配器列表</span></span><br><span class="line">	<span class="function"><span class="title">fprintf</span>(stderr,"\nUnable to open the adapter. %s <span class="keyword">is</span> <span class="built_in">not</span> supported <span class="keyword">by</span> WinPcap\n", d2-&gt;</span><span class="keyword">name</span>);</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>接下来用用于发送的handle处理器来扫描它的局域网IP，获得局域网内的MAC地址，记录在一个表中,存放IP和MAC的对应关系。 这个表可以用结构体数组来保存，比如可以这样:</p>
                  <figure class="highlight routeros">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">struct ip_mac_list&#123;</span><br><span class="line">	IpAddress ip;</span><br><span class="line">	unsigned char mac[6];</span><br><span class="line">&#125;;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <figure class="highlight angelscript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">ip_mac_list  list[<span class="number">256</span>];                       <span class="comment">//存储IP和MAC地址的对应表</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>那么以上便是准备工作，我们完成了两个网卡的打开，发送网卡扫描获取局域网MAC，接下来便是最重要的监听加转发。 那么这个怎办？那就开一个新线程。 让我们声明一个新的路由线程。</p>
                  <figure class="highlight lisp">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">DWORD WINAPI RouteThread(<span class="name">LPVOID</span> lpParameter)<span class="comment">;</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>那么线程要接收进来什么参数呢？ 首先必须要的是两个网卡处理器，在main方法中已经做好初始化的adhandle和adhandle2，另外还有alldevs，可以持有这个指针来释放设备列表，出现错误时释放资源并退出。 初级功能中声明过了 struct sparam sp; struct gparam gp; 这两个就是发送ARP线程和接收ARP线程中的两个参数，那么仿照这个功能，我们定义一个新的结构体</p>
                  <figure class="highlight cpp">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">rparam</span>&#123;</span></span><br><span class="line">	<span class="keyword">pcap_t</span> *adhandle_rec;</span><br><span class="line">	<span class="keyword">pcap_t</span> *adhandle_send;</span><br><span class="line">	<span class="keyword">pcap_if_t</span>  * alldevs;       <span class="comment">//所有网络适配器</span></span><br><span class="line">&#125;;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>在main方法中把它来初始化赋值</p>
                  <figure class="highlight abnf">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">rp.adhandle_send = adhandle<span class="comment">;</span></span><br><span class="line">	rp.adhandle_rec = adhandle2<span class="comment">;</span></span><br><span class="line">	rp.alldevs = alldevs<span class="comment">;</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>当做参数传入这个线程</p>
                  <figure class="highlight lisp">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">routethread = CreateThread(<span class="name">NULL</span>, <span class="number">0</span>, (<span class="name">LPTHREAD_START_ROUTINE</span>) RouteThread, <span class="symbol">&amp;rp</span>,</span><br><span class="line">			<span class="number">0</span>, NULL)<span class="comment">;</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>其中第四个参数就是传递了这个结构体进去。注意这个语句最好不要直接放在main方法中直接调用，可以在全部获取完MAC地址之后再开启这个线程。 那么接下来就说一下这个线程都干了些什么，只简略说一下核心部分。 首先开启了这个线程之后会一直都在执行，那么就可以加入</p>
                  <figure class="highlight lisp">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">while((<span class="name">res</span> = pcap_next_ex(<span class="name">adhandle2</span>,<span class="symbol">&amp;header</span>,<span class="symbol">&amp;pkt_data</span>))&gt;=0)</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>这样的while判断语句来一直监听数据包的接收，然后解析数据。</p>
                  <figure class="highlight perl">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">ethernet =  (EthernetHeader *)(pkt_data);</span><br><span class="line">			<span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;<span class="number">6</span>;i++)&#123;</span><br><span class="line">				sou_mac[i] = ethernet-&gt;SourMAC[i];</span><br><span class="line">			&#125;</span><br><span class="line">			<span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;<span class="number">6</span>;i++)&#123;</span><br><span class="line">				des_mac[i] = ethernet-&gt;DestMAC[i];</span><br><span class="line">			&#125;</span><br><span class="line">			// 获得IP数据包头部的位置</span><br><span class="line">			ip = (IpHeader *) (pkt_data +<span class="number">14</span>);    <span class="regexp">//</span><span class="number">14</span>为以太网帧头部长度</span><br><span class="line">			//获得TCP头部的位置</span><br><span class="line">			ip_len = (ip-&gt;Version_HLen &amp; <span class="number">0xf</span>) *<span class="number">4</span>;</span><br><span class="line">			tcp = (TcpHeader *)((u_char *)ip+ip_len);</span><br><span class="line">			data = (char *)((u_char *)tcp+<span class="number">20</span>);</span><br><span class="line">			<span class="keyword">printf</span>(<span class="string">"data:%s\n"</span>,data);</span><br><span class="line">			<span class="keyword">printf</span>(<span class="string">"ip:"</span>);</span><br><span class="line">			<span class="keyword">printf</span>(<span class="string">"%d.%d.%d.%d -&gt; %d.%d.%d.%d\n"</span>,</span><br><span class="line">					ip-&gt;SourceAddr.byte1,</span><br><span class="line">					ip-&gt;SourceAddr.byte2,</span><br><span class="line">					ip-&gt;SourceAddr.byte3,</span><br><span class="line">					ip-&gt;SourceAddr.byte4,</span><br><span class="line">				    ip-&gt;DestinationAddr.byte1,</span><br><span class="line">				    ip-&gt;DestinationAddr.byte2,</span><br><span class="line">				    ip-&gt;DestinationAddr.byte3,</span><br><span class="line">				    ip-&gt;DestinationAddr.byte4);</span><br><span class="line">			 <span class="keyword">printf</span>(<span class="string">"sou_mac:%02x-%02x-%02x-%02x-%02x-%02x\n"</span>, sou_mac[<span class="number">0</span>], sou_mac[<span class="number">1</span>], sou_mac[<span class="number">2</span>],</span><br><span class="line">			    sou_mac[<span class="number">3</span>], sou_mac[<span class="number">4</span>], sou_mac[<span class="number">5</span>]);</span><br><span class="line">			<span class="keyword">printf</span>(<span class="string">"des_mac:%02x-%02x-%02x-%02x-%02x-%02x\n"</span>, des_mac[<span class="number">0</span>], des_mac[<span class="number">1</span>], des_mac[<span class="number">2</span>],</span><br><span class="line">			    des_mac[<span class="number">3</span>], des_mac[<span class="number">4</span>], des_mac[<span class="number">5</span>]);</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>然后接下来每接收到一个数据，就进行构建新的帧转发出去，目的MAC先匹配list表，如果list没有找到，那么我让他指定了一个mac，比如广播MAC。源MAC地址则赋值网卡的MAC地址。 注意，传统以太网中数据长度为45-1500，那么我在构建前把解析出的data作了下判断长度再构建，因为我已经把sendbuffer声明为一个固定长度了，为了防止越界，我先进行一个长度判断。</p>
                  <figure class="highlight lsl">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="comment">//以下开始构建帧发送</span></span><br><span class="line">		<span class="comment">//首先判断data最大值小于1500</span></span><br><span class="line">		if(strlen(data)&lt;<span class="number">1500</span>)&#123;</span><br><span class="line">			<span class="comment">//目的MAC</span></span><br><span class="line">			BYTE send_destmac[<span class="number">6</span>];</span><br><span class="line">			bool findMac = false;</span><br><span class="line">			for(int c = <span class="number">0</span>;c&lt;con;c++)&#123;</span><br><span class="line">				if(ip-&gt;DestinationAddr.byte1 ==  <span class="type">list</span>[c].ip.byte1&amp;&amp;</span><br><span class="line">					ip-&gt;DestinationAddr.byte2 == <span class="type">list</span>[c].ip.byte2&amp;&amp;</span><br><span class="line">					ip-&gt;DestinationAddr.byte3 == <span class="type">list</span>[c].ip.byte3&amp;&amp;</span><br><span class="line">					ip-&gt;DestinationAddr.byte4 == <span class="type">list</span>[c].ip.byte4)</span><br><span class="line">				&#123;</span><br><span class="line">					printf(<span class="string">"Find its MAC!<span class="subst">\n</span>"</span>);</span><br><span class="line">					findMac = true;</span><br><span class="line">					send_destmac[<span class="number">0</span>] = <span class="type">list</span>[c].mac[<span class="number">0</span>];   </span><br><span class="line">					send_destmac[<span class="number">1</span>] = <span class="type">list</span>[c].mac[<span class="number">1</span>];</span><br><span class="line">					send_destmac[<span class="number">2</span>] = <span class="type">list</span>[c].mac[<span class="number">2</span>];</span><br><span class="line">					send_destmac[<span class="number">3</span>] = <span class="type">list</span>[c].mac[<span class="number">3</span>];</span><br><span class="line">					send_destmac[<span class="number">4</span>] = <span class="type">list</span>[c].mac[<span class="number">4</span>];</span><br><span class="line">					send_destmac[<span class="number">5</span>] = <span class="type">list</span>[c].mac[<span class="number">5</span>];</span><br><span class="line">				&#125;</span><br><span class="line">			&#125;</span><br><span class="line">			if(!findMac)&#123;</span><br><span class="line">				send_destmac[<span class="number">0</span>] = <span class="number">0xff</span>;   </span><br><span class="line">				send_destmac[<span class="number">1</span>] = <span class="number">0xff</span>;   </span><br><span class="line">				send_destmac[<span class="number">2</span>] = <span class="number">0xff</span>;   </span><br><span class="line">				send_destmac[<span class="number">3</span>] = <span class="number">0xff</span>;   </span><br><span class="line">				send_destmac[<span class="number">4</span>] = <span class="number">0xff</span>;   </span><br><span class="line">				send_destmac[<span class="number">5</span>] = <span class="number">0xff</span>;   </span><br><span class="line">			&#125;</span><br><span class="line">			printf(<span class="string">"destmac:%02x-%02x-%02x-%02x-%02x-%02x<span class="subst">\n</span>"</span>,</span><br><span class="line">				send_destmac[<span class="number">0</span>],send_destmac[<span class="number">1</span>],send_destmac[<span class="number">2</span>],</span><br><span class="line">				send_destmac[<span class="number">3</span>],send_destmac[<span class="number">4</span>],send_destmac[<span class="number">5</span>]</span><br><span class="line">				);</span><br><span class="line">			memcpy(send_ethernet.DestMAC, send_destmac, <span class="number">6</span>);</span><br><span class="line">			<span class="comment">//源MAC地址</span></span><br><span class="line">			BYTE send_hostmac[<span class="number">6</span>];</span><br><span class="line">			<span class="comment">//源MAC地址</span></span><br><span class="line">			send_hostmac[<span class="number">0</span>] = local_mac[<span class="number">0</span>];     <span class="comment">//赋值本地MAC地址</span></span><br><span class="line">			send_hostmac[<span class="number">1</span>] = local_mac[<span class="number">1</span>];</span><br><span class="line">			send_hostmac[<span class="number">2</span>] = local_mac[<span class="number">2</span>];</span><br><span class="line">			send_hostmac[<span class="number">3</span>] = local_mac[<span class="number">3</span>];</span><br><span class="line">			send_hostmac[<span class="number">4</span>] = local_mac[<span class="number">4</span>];</span><br><span class="line">			send_hostmac[<span class="number">5</span>] = local_mac[<span class="number">5</span>];</span><br><span class="line">			<span class="comment">//赋值源MAC地址</span></span><br><span class="line">			memcpy(send_ethernet.SourMAC, send_hostmac, <span class="number">6</span>);</span><br><span class="line">			send_ethernet.EthType = htons(<span class="number">0x0800</span>);</span><br><span class="line">			<span class="comment">//赋值SendBuffer</span></span><br><span class="line">			memcpy(&amp;SendBuffer, &amp;send_ethernet, sizeof(struct EthernetHeader));</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>以上只是赋值了帧头，至于IP头，TCP头，数据的赋值就参照初级功能的来赋值吧，不要忘了校验和的检验。好，大体上就是这样，接受来数据包并转发出去的原理就是这样。</p>
                  <h3 id="三、接收"><a href="#三、接收" class="headerlink" title="三、接收"></a>三、接收</h3>
                  <p>不用多改，就是初级功能中的接收，在此写一写小小的优化措施，防止接收到过多的数据帧而造成不断乱蹦，导致你看不到接收的东西。 在打印的时候加一个过滤就好了。部分代码如下： 在main方法中提示用户输入要接收的IP地址</p>
                  <figure class="highlight angelscript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">printf(<span class="string">"请输入要接收的IP地址,输入0.0.0.0代表全部接收,请输入\n"</span>);</span><br><span class="line">	<span class="built_in">bool</span> receiveAll = <span class="literal">false</span>;</span><br><span class="line">	u_int ip1,ip2,ip3,ip4;</span><br><span class="line">	<span class="built_in">bool</span> legal = <span class="literal">false</span>;</span><br><span class="line">	<span class="keyword">while</span>(!legal)&#123;</span><br><span class="line">		scanf_s(<span class="string">"%d.%d.%d.%d"</span>,&amp;ip1,&amp;ip2,&amp;ip3,&amp;ip4);</span><br><span class="line">		<span class="keyword">if</span>(ip1==<span class="number">0</span>&amp;&amp;ip2==<span class="number">0</span>&amp;&amp;ip3==<span class="number">0</span>&amp;&amp;ip4==<span class="number">0</span>)&#123;</span><br><span class="line">			receiveAll = <span class="literal">true</span>;</span><br><span class="line">			legal = <span class="literal">true</span>;</span><br><span class="line">			<span class="keyword">break</span>;</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="keyword">if</span>(ip1&lt;<span class="number">0</span>||ip1&gt;<span class="number">255</span>||ip2&lt;<span class="number">0</span>||ip2&gt;<span class="number">255</span>||ip3&lt;<span class="number">0</span>||ip3&gt;<span class="number">255</span>||ip4&lt;<span class="number">1</span>||ip4&gt;<span class="number">254</span>)&#123;</span><br><span class="line">			legal = <span class="literal">false</span>;</span><br><span class="line">			printf(<span class="string">"对不起,IP输入不合法,请重新输入:\n"</span>);</span><br><span class="line">		&#125;<span class="keyword">else</span>&#123;</span><br><span class="line">			legal = <span class="literal">true</span>;</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>打印时的判断</p>
                  <figure class="highlight perl">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="keyword">if</span>(receiveAll||(ip-&gt;SourceAddr.byte1==ip1&amp;&amp;</span><br><span class="line">					ip-&gt;SourceAddr.byte2==ip2&amp;&amp;</span><br><span class="line">					ip-&gt;SourceAddr.byte3==ip3&amp;&amp;</span><br><span class="line">					ip-&gt;SourceAddr.byte4==ip4))&#123;</span><br><span class="line">					<span class="keyword">printf</span>(<span class="string">"%d.%d.%d.%d.%d -&gt; %d.%d.%d.%d.%d\n"</span>,</span><br><span class="line">					ip-&gt;SourceAddr.byte1,</span><br><span class="line">					ip-&gt;SourceAddr.byte2,</span><br><span class="line">					ip-&gt;SourceAddr.byte3,</span><br><span class="line">					ip-&gt;SourceAddr.byte4,</span><br><span class="line">				    sport,</span><br><span class="line">				    ip-&gt;DestinationAddr.byte1,</span><br><span class="line">				    ip-&gt;DestinationAddr.byte2,</span><br><span class="line">				    ip-&gt;DestinationAddr.byte3,</span><br><span class="line">				    ip-&gt;DestinationAddr.byte4,</span><br><span class="line">				    dport);</span><br><span class="line">			    <span class="keyword">printf</span>(<span class="string">"sou_mac:%02x-%02x-%02x-%02x-%02x-%02x\n"</span>, sou_mac[<span class="number">0</span>], sou_mac[<span class="number">1</span>], sou_mac[<span class="number">2</span>],</span><br><span class="line">			    sou_mac[<span class="number">3</span>], sou_mac[<span class="number">4</span>], sou_mac[<span class="number">5</span>]);</span><br><span class="line">				<span class="keyword">printf</span>(<span class="string">"des_mac:%02x-%02x-%02x-%02x-%02x-%02x\n"</span>, des_mac[<span class="number">0</span>], des_mac[<span class="number">1</span>], des_mac[<span class="number">2</span>],</span><br><span class="line">			    des_mac[<span class="number">3</span>], des_mac[<span class="number">4</span>], des_mac[<span class="number">5</span>]);</span><br><span class="line">				<span class="keyword">printf</span>(<span class="string">"%s\n"</span>,data);</span><br><span class="line">				<span class="keyword">printf</span>(<span class="string">"-----------------------------------------------------\n"</span>);</span><br><span class="line">			&#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>好，代码就先放送这么多，具体的实现只要有了思路我相信肯定不难，如有问题，欢迎与我交流。</p>
                  </p>
                </div>
              </div>
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-user"></i>
                  </span>
                  <span class="post-meta-item-text">作者</span>
                  <span><a href="/authors/崔庆才" class="author" itemprop="url" rel="index">崔庆才</a></span>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>
                  <time title="创建时间：2015-07-13 01:19:22" itemprop="dateCreated datePublished" datetime="2015-07-13T01:19:22+08:00">2015-07-13</time>
                </span>
                <span id="/1922.html" class="post-meta-item leancloud_visitors" data-flag-title="Winpcap网络编程六之两台主机通过中间主机通信" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="fa fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
                <span class="post-meta-item" title="本文字数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-file-word"></i>
                  </span>
                  <span class="post-meta-item-text">本文字数：</span>
                  <span>7.3k</span>
                </span>
                <span class="post-meta-item" title="阅读时长">
                  <span class="post-meta-item-icon">
                    <i class="far fa-clock"></i>
                  </span>
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                  <span>7 分钟</span>
                </span>
              </div>
            </article>
            <article itemscope itemtype="http://schema.org/Article" class="post-block index" lang="zh-CN">
              <link itemprop="mainEntityOfPage" href="https://cuiqingcai.com/1918.html">
              <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
                <meta itemprop="image" content="/images/avatar.png">
                <meta itemprop="name" content="崔庆才">
                <meta itemprop="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
              </span>
              <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
                <meta itemprop="name" content="静觅">
              </span>
              <header class="post-header">
                <h2 class="post-title" itemprop="name headline">
                  <a class="label"> C/C++ <i class="label-arrow"></i>
                  </a>
                  <a href="/1918.html" class="post-title-link" itemprop="url">Winpcap网络编程五之ARP协议获得MAC表及主机通信</a>
                </h2>
              </header>
              <div class="post-body" itemprop="articleBody">
                <div class="thumb">
                  <img itemprop="contentUrl" class="random">
                </div>
                <div class="excerpt">
                  <p>
                  <h2 id="学习文档"><a href="#学习文档" class="headerlink" title="学习文档"></a>学习文档</h2>
                  <p>这里我们直接进入正题吧，关于Winpcap的基础知识讲解这里就不再赘述了。在这里给大家提供一些学习网址 <a href="http://blog.csdn.net/column/details/winpcap.html" target="_blank" rel="noopener">Winpcap网络编程及通信教程</a><a href="http://www.ferrisxu.com/WinPcap/html/" target="_blank" rel="noopener">Winpcap中文技术文档</a></p>
                  <h2 id="学习内容"><a href="#学习内容" class="headerlink" title="学习内容"></a>学习内容</h2>
                  <ul>
                    <li>获取设备列表</li>
                    <li>获取已安装设备的高级信息</li>
                    <li>打开适配器并捕获数据包</li>
                    <li>不用回调方法捕获数据包</li>
                    <li>过滤数据包</li>
                    <li>分析数据包</li>
                    <li>处理脱机堆文件</li>
                    <li>发送数据包</li>
                    <li>收集并统计网络流量</li>
                  </ul>
                  <p>这些内容，在上述两个链接中均已经有了比较详细的讲解，希望对大家有帮助。</p>
                  <h2 id="两台主机通信实战"><a href="#两台主机通信实战" class="headerlink" title="两台主机通信实战"></a>两台主机通信实战</h2>
                  <p>完成两台主机之间的数据通信（数据链路层）</p>
                  <ul>
                    <li>仿真ARP协议获得网段内主机的MAC表</li>
                    <li>使用帧完成两台主机的通信（Hello! I’m …)</li>
                  </ul>
                  <p>首先我们要理解ARP是干嘛的，ARP主要作用就是通过IP地址来获取MAC地址。那么怎样获取呢？本机向局域网内主机发送ARP包，ARP包内包含了目的IP，源IP，目的MAC，源MAC，其中目的MAC地址为广播地址,FF-FF-FF-FF-FF-FF,即向局域网内所有主机发送一个ARP请求，那么其他主机收到这个请求之后则会向请求来源返回一个数据包。在这个返回的数据包中包含了自身的MAC地址。那么本机收到这些返回的数据包进行解析之后便会得到局域网内所有主机的MAC地址了.. 编程开始： 新建一个C++项目，配好环境，引入Winpcap相关的库，这些不再赘述。 头文件引入</p>
                  <figure class="highlight dts">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="meta">#<span class="meta-keyword">define</span> HAVE_REMOTE</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> WPCAP</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdlib.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;pcap.h&gt;</span></span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>在main函数中首先声明一系列变量如下</p>
                  <figure class="highlight cpp">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="keyword">char</span> *ip_addr;                                    <span class="comment">//IP地址</span></span><br><span class="line"><span class="keyword">char</span> *ip_netmask;                             <span class="comment">//子网掩码</span></span><br><span class="line"><span class="keyword">unsigned</span> <span class="keyword">char</span> *ip_mac;          <span class="comment">//本机MAC地址</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>为这三个变量分配地址空间</p>
                  <figure class="highlight cpp">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">ip_addr = (<span class="keyword">char</span> *) <span class="built_in">malloc</span>(<span class="keyword">sizeof</span>(<span class="keyword">char</span>) * <span class="number">16</span>); <span class="comment">//申请内存存放IP地址</span></span><br><span class="line">	<span class="keyword">if</span> (ip_addr == <span class="literal">NULL</span>)</span><br><span class="line">	&#123;</span><br><span class="line">		<span class="built_in">printf</span>(<span class="string">"申请内存存放IP地址失败!\n"</span>);</span><br><span class="line">		<span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">	&#125;</span><br><span class="line">	ip_netmask = (<span class="keyword">char</span> *) <span class="built_in">malloc</span>(<span class="keyword">sizeof</span>(<span class="keyword">char</span>) * <span class="number">16</span>); <span class="comment">//申请内存存放NETMASK地址</span></span><br><span class="line">	<span class="keyword">if</span> (ip_netmask == <span class="literal">NULL</span>)</span><br><span class="line">	&#123;</span><br><span class="line">		<span class="built_in">printf</span>(<span class="string">"申请内存存放NETMASK地址失败!\n"</span>);</span><br><span class="line">		<span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">	&#125;</span><br><span class="line">	ip_mac = (<span class="keyword">unsigned</span> <span class="keyword">char</span> *) <span class="built_in">malloc</span>(<span class="keyword">sizeof</span>(<span class="keyword">unsigned</span> <span class="keyword">char</span>) * <span class="number">6</span>); <span class="comment">//申请内存存放MAC地址</span></span><br><span class="line">	<span class="keyword">if</span> (ip_mac == <span class="literal">NULL</span>)</span><br><span class="line">	&#123;</span><br><span class="line">		<span class="built_in">printf</span>(<span class="string">"申请内存存放MAC地址失败!\n"</span>);</span><br><span class="line">		<span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">	&#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>接下来就是烂大街的程序,获取适配器列表并选中相应的适配器,注释已经在代码中了,如果还有不明白的请参照前几次的讲解。</p>
                  <figure class="highlight xl">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="comment">//获取本地适配器列表</span></span><br><span class="line">	<span class="keyword">if</span>(pcap_findalldevs_ex(PCAP_SRC_IF_STRING,NULL,&amp;alldevs,errbuf) == -<span class="number">1</span>)&#123;</span><br><span class="line">		<span class="comment">//结果为-1代表出现获取适配器列表失败</span></span><br><span class="line">		fprintf(stderr,<span class="string">"Error in pcap_findalldevs_ex:\n"</span>,errbuf);</span><br><span class="line">		<span class="comment">//exit(0)代表正常退出,exit(other)为非正常退出,这个值会传给操作系统</span></span><br><span class="line">		exit(<span class="number">1</span>);</span><br><span class="line">	&#125;</span><br><span class="line">	</span><br><span class="line"></span><br><span class="line">	<span class="function"><span class="title">for</span>(d = alldevs;d !=NULL;d = d-&gt;</span>next)&#123;</span><br><span class="line">		<span class="function"><span class="title">printf</span>("-----------------------------------------------------------------\nnumber:%d\nname:%s\n",++i,d-&gt;</span><span class="keyword">name</span>);</span><br><span class="line">		<span class="function"><span class="title">if</span>(d-&gt;</span>description)&#123;</span><br><span class="line">			<span class="comment">//打印适配器的描述信息</span></span><br><span class="line">			<span class="function"><span class="title">printf</span>("description:%s\n",d-&gt;</span>description);</span><br><span class="line">		&#125;<span class="keyword">else</span>&#123;</span><br><span class="line">			<span class="comment">//适配器不存在描述信息</span></span><br><span class="line">			printf(<span class="string">"description:%s"</span>,<span class="string">"no description\n"</span>);</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="comment">//打印本地环回地址</span></span><br><span class="line">		 <span class="function"><span class="title">printf</span>("\tLoopback: %s\n",(d-&gt;</span>flags &amp; PCAP_IF_LOOPBACK)?<span class="string">"yes"</span>:<span class="string">"no"</span>);</span><br><span class="line">		 <span class="comment">/**</span></span><br><span class="line"><span class="comment">		 pcap_addr *  next     指向下一个地址的指针</span></span><br><span class="line"><span class="comment">		 sockaddr *  addr       IP地址</span></span><br><span class="line"><span class="comment">		 sockaddr *  netmask  子网掩码</span></span><br><span class="line"><span class="comment">		 sockaddr *  broadaddr   广播地址</span></span><br><span class="line"><span class="comment">		 sockaddr *  dstaddr        目的地址</span></span><br><span class="line"><span class="comment">		 */</span></span><br><span class="line">		 pcap_addr_t *a;       <span class="comment">//网络适配器的地址用来存储变量</span></span><br><span class="line">		 <span class="function"><span class="title">for</span>(a = d-&gt;</span><span class="function"><span class="title">addresses</span>;a;a = a-&gt;</span>next)&#123;</span><br><span class="line">			 <span class="comment">//sa_family代表了地址的类型,是IPV4地址类型还是IPV6地址类型</span></span><br><span class="line">			 <span class="function"><span class="title">switch</span> (a-&gt;</span><span class="function"><span class="title">addr</span>-&gt;</span>sa_family)</span><br><span class="line">			 &#123;</span><br><span class="line">				 case AF_INET:  <span class="comment">//代表IPV4类型地址</span></span><br><span class="line">					 printf(<span class="string">"Address Family Name:AF_INET\n"</span>);</span><br><span class="line">					 <span class="function"><span class="title">if</span>(a-&gt;</span>addr)&#123;</span><br><span class="line">						 <span class="comment">//-&gt;的优先级等同于括号,高于强制类型转换,因为addr为sockaddr类型，对其进行操作须转换为sockaddr_in类型</span></span><br><span class="line">						 <span class="function"><span class="title">printf</span>("Address:%s\n",iptos(((struct sockaddr_in *)a-&gt;</span><span class="function"><span class="title">addr</span>)-&gt;</span>sin_addr.s_addr));</span><br><span class="line">					 &#125;</span><br><span class="line">					<span class="function"><span class="title">if</span> (a-&gt;</span>netmask)&#123;</span><br><span class="line">						 <span class="function"><span class="title">printf</span>("\tNetmask: %s\n",iptos(((struct sockaddr_in *)a-&gt;</span><span class="function"><span class="title">netmask</span>)-&gt;</span>sin_addr.s_addr));</span><br><span class="line">					&#125;</span><br><span class="line">					<span class="function"><span class="title">if</span> (a-&gt;</span>broadaddr)&#123;</span><br><span class="line">						   <span class="function"><span class="title">printf</span>("\tBroadcast Address: %s\n",iptos(((struct sockaddr_in *)a-&gt;</span><span class="function"><span class="title">broadaddr</span>)-&gt;</span>sin_addr.s_addr));</span><br><span class="line">					 &#125;</span><br><span class="line">					 <span class="function"><span class="title">if</span> (a-&gt;</span>dstaddr)&#123;</span><br><span class="line">						   <span class="function"><span class="title">printf</span>("\tDestination Address: %s\n",iptos(((struct sockaddr_in *)a-&gt;</span><span class="function"><span class="title">dstaddr</span>)-&gt;</span>sin_addr.s_addr));</span><br><span class="line">					 &#125;</span><br><span class="line">        			 break;</span><br><span class="line">				 case AF_INET6: <span class="comment">//代表IPV6类型地址</span></span><br><span class="line">					 printf(<span class="string">"Address Family Name:AF_INET6\n"</span>);</span><br><span class="line">					 printf(<span class="string">"this is an IPV6 address\n"</span>);</span><br><span class="line">					 break;</span><br><span class="line">				 default:</span><br><span class="line">					 break;</span><br><span class="line">			 &#125;</span><br><span class="line">		 &#125;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="comment">//i为0代表上述循环未进入,即没有找到适配器,可能的原因为Winpcap没有安装导致未扫描到</span></span><br><span class="line">	<span class="keyword">if</span>(i == <span class="number">0</span>)&#123;</span><br><span class="line">		printf(<span class="string">"interface not found,please check winpcap installation"</span>);</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	int num;</span><br><span class="line">	printf(<span class="string">"Enter the interface number(1-%d):"</span>,i);</span><br><span class="line">	<span class="comment">//让用户选择选择哪个适配器进行抓包</span></span><br><span class="line">	scanf_s(<span class="string">"%d"</span>,&amp;num);</span><br><span class="line">	printf(<span class="string">"\n"</span>);</span><br><span class="line"></span><br><span class="line">	<span class="comment">//用户输入的数字超出合理范围</span></span><br><span class="line">	<span class="keyword">if</span>(num&lt;<span class="number">1</span>||num&gt;i)&#123;</span><br><span class="line">		printf(<span class="string">"number out of range\n"</span>);</span><br><span class="line">		pcap_freealldevs(alldevs);</span><br><span class="line">		return -<span class="number">1</span>;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="comment">//跳转到选中的适配器</span></span><br><span class="line">	<span class="function"><span class="title">for</span>(d=alldevs, i=0; i&lt; num-1 ; d=d-&gt;</span>next, i++);</span><br><span class="line"></span><br><span class="line">	<span class="comment">//运行到此处说明用户的输入是合法的</span></span><br><span class="line">	<span class="function"><span class="title">if</span>((adhandle = pcap_open(d-&gt;</span><span class="keyword">name</span>,		<span class="comment">//设备名称</span></span><br><span class="line">														<span class="number">65535</span>,       <span class="comment">//存放数据包的内容长度</span></span><br><span class="line">														PCAP_OPENFLAG_PROMISCUOUS,  <span class="comment">//混杂模式</span></span><br><span class="line">														<span class="number">1000</span>,           <span class="comment">//超时时间</span></span><br><span class="line">														NULL,          <span class="comment">//远程验证</span></span><br><span class="line">														errbuf         <span class="comment">//错误缓冲</span></span><br><span class="line">														)) == NULL)&#123;</span><br><span class="line">        <span class="comment">//打开适配器失败,打印错误并释放适配器列表</span></span><br><span class="line">		<span class="function"><span class="title">fprintf</span>(stderr,"\nUnable to open the adapter. %s <span class="keyword">is</span> <span class="built_in">not</span> supported <span class="keyword">by</span> WinPcap\n", d-&gt;</span><span class="keyword">name</span>);</span><br><span class="line">        <span class="comment">// 释放设备列表 </span></span><br><span class="line">        pcap_freealldevs(alldevs);</span><br><span class="line">        return -<span class="number">1</span>;</span><br><span class="line">	&#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>上述代码中需要另外声明的有：</p>
                  <figure class="highlight cpp">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="keyword">pcap_if_t</span>  * alldevs;       <span class="comment">//所有网络适配器</span></span><br><span class="line"><span class="keyword">pcap_if_t</span>  *d;					<span class="comment">//选中的网络适配器</span></span><br><span class="line"><span class="keyword">char</span> errbuf[PCAP_ERRBUF_SIZE];   <span class="comment">//错误缓冲区,大小为256</span></span><br><span class="line"><span class="keyword">pcap_t</span> *adhandle;           <span class="comment">//捕捉实例,是pcap_open返回的对象</span></span><br><span class="line"><span class="keyword">int</span> i = <span class="number">0</span>;                            <span class="comment">//适配器计数变量</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <figure class="highlight cpp">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="function"><span class="keyword">char</span> *<span class="title">iptos</span><span class="params">(u_long in)</span></span>;       <span class="comment">//u_long即为 unsigned long</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <figure class="highlight angelscript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="comment">/* 将数字类型的IP地址转换成字符串类型的 */</span></span><br><span class="line">#define IPTOSBUFFERS    <span class="number">12</span></span><br><span class="line">char *iptos(u_long <span class="keyword">in</span>)</span><br><span class="line">&#123;</span><br><span class="line">    static char output[IPTOSBUFFERS][<span class="number">3</span>*<span class="number">4</span>+<span class="number">3</span>+<span class="number">1</span>];</span><br><span class="line">    static short which;</span><br><span class="line">    u_char *p;</span><br><span class="line"></span><br><span class="line">    p = (u_char *)&amp;<span class="keyword">in</span>;</span><br><span class="line">    which = (which + <span class="number">1</span> == IPTOSBUFFERS ? <span class="number">0</span> : which + <span class="number">1</span>);</span><br><span class="line">    sprintf_s(output[which], <span class="string">"%d.%d.%d.%d"</span>, p[<span class="number">0</span>], p[<span class="number">1</span>], p[<span class="number">2</span>], p[<span class="number">3</span>]);</span><br><span class="line">    <span class="keyword">return</span> output[which];</span><br><span class="line">&#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>到此程序应该会编译通过，可以试着编译一下运行。 GO ON… 接下来我们首先要用ifget方法获取自身的IP和子网掩码 函数声明：</p>
                  <figure class="highlight cpp">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">ifget</span><span class="params">(<span class="keyword">pcap_if_t</span> *d, <span class="keyword">char</span> *ip_addr, <span class="keyword">char</span> *ip_netmask)</span></span>;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <figure class="highlight livescript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="regexp">//获取IP和子网掩码赋值为ip_addr和ip_netmask</span></span><br><span class="line"><span class="regexp">void ifget(pcap_if_t *d, char *ip_addr, char *ip_netmask) &#123;</span></span><br><span class="line"><span class="regexp">	pcap_addr_t *a;</span></span><br><span class="line"><span class="regexp">	//</span>遍历所有的地址,a代表一个pcap_addr</span><br><span class="line">	<span class="keyword">for</span> (a = d-&gt;addresses; a; a = a-&gt;next) &#123;</span><br><span class="line">		<span class="keyword">switch</span> (a-&gt;addr-&gt;sa_family) &#123;</span><br><span class="line">		<span class="keyword">case</span> AF_INET:  <span class="regexp">//sa_family ：是2字节的地址家族，一般都是“AF_xxx”的形式。通常用的都是AF_INET。代表IPV4</span></span><br><span class="line"><span class="regexp">			if (a-&gt;addr) &#123;</span></span><br><span class="line"><span class="regexp">				char *ipstr;</span></span><br><span class="line"><span class="regexp">				//</span>将地址转化为字符串</span><br><span class="line">				ipstr = iptos<span class="function"><span class="params">(((struct sockaddr_in *) a-&gt;addr)-&gt;sin_addr.s_addr)</span>; //*<span class="title">ip_addr</span></span></span><br><span class="line"><span class="function">				<span class="title">printf</span><span class="params">(<span class="string">"ipstr:%s\n"</span>,ipstr)</span>;</span></span><br><span class="line"><span class="function">				<span class="title">memcpy</span><span class="params">(ip_addr, ipstr, <span class="number">16</span>)</span>;</span></span><br><span class="line"><span class="function">			&#125;</span></span><br><span class="line"><span class="function">			<span class="title">if</span> <span class="params">(a-&gt;netmask)</span> &#123;</span></span><br><span class="line"><span class="function">				<span class="title">char</span> *<span class="title">netmaskstr</span>;</span></span><br><span class="line"><span class="function">				<span class="title">netmaskstr</span> = <span class="title">iptos</span><span class="params">(((struct sockaddr_in *) a-&gt;netmask)-&gt;sin_addr.s_addr)</span>;</span></span><br><span class="line"><span class="function">				<span class="title">printf</span><span class="params">(<span class="string">"netmask:%s\n"</span>,netmaskstr)</span>;</span></span><br><span class="line"><span class="function">				<span class="title">memcpy</span><span class="params">(ip_netmask, netmaskstr, <span class="number">16</span>)</span>;</span></span><br><span class="line"><span class="function">			&#125;</span></span><br><span class="line"><span class="function">		<span class="title">case</span> <span class="title">AF_INET6</span>:</span></span><br><span class="line"><span class="function">			<span class="title">break</span>;</span></span><br><span class="line"><span class="function">		&#125;</span></span><br><span class="line"><span class="function">	&#125;</span></span><br><span class="line"><span class="function">&#125;</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>main函数继续写，如下调用，之前声明的ip_addr和ip_netmask就已经被赋值了</p>
                  <figure class="highlight brainfuck">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="comment">ifget(d</span><span class="string">,</span> <span class="comment">ip_addr</span><span class="string">,</span> <span class="comment">ip_netmask);</span> <span class="comment">//获取所选网卡的基本信息</span>--<span class="comment">掩码</span>--<span class="comment">IP地址</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>到现在我们已经获取到了本机的IP和子网掩码，下一步发送一个ARP请求来获取自身的MAC地址 这个ARP请求的源IP地址就随便指定了，就相当于你构造了一个外来的ARP请求，本机捕获到了请求，然后发送回应给对方的数据包也被本机捕获到了并解析出来了。解析了自己发出去的数据包而已。 那么我们就声明一个函数并实现：</p>
                  <figure class="highlight reasonml">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="built_in">int</span> <span class="constructor">GetSelfMac(<span class="params">pcap_t</span> <span class="operator">*</span><span class="params">adhandle</span>, <span class="params">const</span> <span class="params">char</span> <span class="operator">*</span><span class="params">ip_addr</span>, <span class="params">unsigned</span> <span class="params">char</span> <span class="operator">*</span><span class="params">ip_mac</span>)</span>;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <figure class="highlight cpp">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="comment">// 获取自己主机的MAC地址</span></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">GetSelfMac</span><span class="params">(<span class="keyword">pcap_t</span> *adhandle, <span class="keyword">const</span> <span class="keyword">char</span> *ip_addr, <span class="keyword">unsigned</span> <span class="keyword">char</span> *ip_mac)</span> </span>&#123;</span><br><span class="line">	<span class="keyword">unsigned</span> <span class="keyword">char</span> sendbuf[<span class="number">42</span>]; <span class="comment">//arp包结构大小</span></span><br><span class="line">	<span class="keyword">int</span> i = <span class="number">-1</span>;</span><br><span class="line">	<span class="keyword">int</span> res;</span><br><span class="line">	EthernetHeader eh; <span class="comment">//以太网帧头</span></span><br><span class="line">	Arpheader ah;  <span class="comment">//ARP帧头</span></span><br><span class="line">	<span class="class"><span class="keyword">struct</span> <span class="title">pcap_pkthdr</span> * <span class="title">pkt_header</span>;</span></span><br><span class="line">	<span class="keyword">const</span> u_char * pkt_data;</span><br><span class="line">	<span class="comment">//将已开辟内存空间 eh.dest_mac_add 的首 6个字节的值设为值 0xff。</span></span><br><span class="line">	<span class="built_in">memset</span>(eh.DestMAC, <span class="number">0xff</span>, <span class="number">6</span>); <span class="comment">//目的地址为全为广播地址</span></span><br><span class="line">	<span class="built_in">memset</span>(eh.SourMAC, <span class="number">0x0f</span>, <span class="number">6</span>);</span><br><span class="line">	<span class="built_in">memset</span>(ah.DestMacAdd, <span class="number">0x0f</span>, <span class="number">6</span>);</span><br><span class="line">	<span class="built_in">memset</span>(ah.SourceMacAdd, <span class="number">0x00</span>, <span class="number">6</span>);</span><br><span class="line">	<span class="comment">//htons将一个无符号短整型的主机数值转换为网络字节顺序</span></span><br><span class="line">	eh.EthType = htons(ETH_ARP);</span><br><span class="line">	ah.HardwareType= htons(ARP_HARDWARE);</span><br><span class="line">	ah.ProtocolType = htons(ETH_IP);</span><br><span class="line">	ah.HardwareAddLen = <span class="number">6</span>;</span><br><span class="line">	ah.ProtocolAddLen = <span class="number">4</span>;</span><br><span class="line">	ah.SourceIpAdd = inet_addr(<span class="string">"100.100.100.100"</span>); <span class="comment">//随便设的请求方ip</span></span><br><span class="line">	ah.OperationField = htons(ARP_REQUEST);</span><br><span class="line">	ah.DestIpAdd = inet_addr(ip_addr);</span><br><span class="line">	<span class="built_in">memset</span>(sendbuf, <span class="number">0</span>, <span class="keyword">sizeof</span>(sendbuf));</span><br><span class="line">	<span class="built_in">memcpy</span>(sendbuf, &amp;eh, <span class="keyword">sizeof</span>(eh));</span><br><span class="line">	<span class="built_in">memcpy</span>(sendbuf + <span class="keyword">sizeof</span>(eh), &amp;ah, <span class="keyword">sizeof</span>(ah));</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">"%s"</span>,sendbuf);</span><br><span class="line">	<span class="keyword">if</span> (pcap_sendpacket(adhandle, sendbuf, <span class="number">42</span>) == <span class="number">0</span>) &#123;</span><br><span class="line">		<span class="built_in">printf</span>(<span class="string">"\nPacketSend succeed\n"</span>);</span><br><span class="line">	&#125; <span class="keyword">else</span> &#123;</span><br><span class="line">		<span class="built_in">printf</span>(<span class="string">"PacketSendPacket in getmine Error: %d\n"</span>, GetLastError());</span><br><span class="line">		<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="comment">//从interface或离线记录文件获取一个报文</span></span><br><span class="line">	<span class="comment">//pcap_next_ex(pcap_t* p,struct pcap_pkthdr** pkt_header,const u_char** pkt_data)</span></span><br><span class="line">	<span class="keyword">while</span> ((res = pcap_next_ex(adhandle, &amp;pkt_header, &amp;pkt_data)) &gt;= <span class="number">0</span>) &#123;</span><br><span class="line">		<span class="keyword">if</span> (*(<span class="keyword">unsigned</span> short *) (pkt_data + <span class="number">12</span>) == htons(ETH_ARP)</span><br><span class="line">				&amp;&amp; *(<span class="keyword">unsigned</span> short*) (pkt_data + <span class="number">20</span>) == htons(ARP_REPLY)</span><br><span class="line">				&amp;&amp; *(<span class="keyword">unsigned</span> <span class="keyword">long</span>*) (pkt_data + <span class="number">38</span>)</span><br><span class="line">						== inet_addr(<span class="string">"100.100.100.100"</span>)) &#123;</span><br><span class="line">			<span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; <span class="number">6</span>; i++) &#123;</span><br><span class="line">				ip_mac[i] = *(<span class="keyword">unsigned</span> <span class="keyword">char</span> *) (pkt_data + <span class="number">22</span> + i);</span><br><span class="line">			&#125;</span><br><span class="line">			<span class="built_in">printf</span>(<span class="string">"获取自己主机的MAC地址成功!\n"</span>);</span><br><span class="line">			<span class="keyword">break</span>;</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">if</span> (i == <span class="number">6</span>) &#123;</span><br><span class="line">		<span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">	&#125; <span class="keyword">else</span> &#123;</span><br><span class="line">		<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>其中我们需要定义一下常量如下</p>
                  <figure class="highlight cpp">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="meta">#<span class="meta-keyword">define</span> ETH_ARP         0x0806  <span class="comment">//以太网帧类型表示后面数据的类型，对于ARP请求或应答来说，该字段的值为x0806</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> ARP_HARDWARE    1  <span class="comment">//硬件类型字段值为表示以太网地址</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> ETH_IP          0x0800  <span class="comment">//协议类型字段表示要映射的协议地址类型值为x0800表示IP地址</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> ARP_REQUEST     1   <span class="comment">//ARP请求</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> ARP_REPLY       2      <span class="comment">//ARP应答</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> HOSTNUM         255   <span class="comment">//主机数量</span></span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>另外发送ARP请求少不了帧头和ARP头的结构，我们需要声明出来，另外我们构建发送包需要再声明两个结构体sparam和gparam</p>
                  <figure class="highlight cpp">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="comment">//帧头部结构体，共14字节</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">EthernetHeader</span></span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">    u_char DestMAC[<span class="number">6</span>];    <span class="comment">//目的MAC地址 6字节</span></span><br><span class="line">    u_char SourMAC[<span class="number">6</span>];   <span class="comment">//源MAC地址 6字节</span></span><br><span class="line">    u_short EthType;         <span class="comment">//上一层协议类型，如0x0800代表上一层是IP协议，0x0806为arp  2字节</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">//28字节ARP帧结构</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">Arpheader</span> &#123;</span></span><br><span class="line">	<span class="keyword">unsigned</span> short HardwareType; <span class="comment">//硬件类型</span></span><br><span class="line">	<span class="keyword">unsigned</span> short ProtocolType; <span class="comment">//协议类型</span></span><br><span class="line">	<span class="keyword">unsigned</span> <span class="keyword">char</span> HardwareAddLen; <span class="comment">//硬件地址长度</span></span><br><span class="line">	<span class="keyword">unsigned</span> <span class="keyword">char</span> ProtocolAddLen; <span class="comment">//协议地址长度</span></span><br><span class="line">	<span class="keyword">unsigned</span> short OperationField; <span class="comment">//操作字段</span></span><br><span class="line">	<span class="keyword">unsigned</span> <span class="keyword">char</span> SourceMacAdd[<span class="number">6</span>]; <span class="comment">//源mac地址</span></span><br><span class="line">	<span class="keyword">unsigned</span> <span class="keyword">long</span> SourceIpAdd; <span class="comment">//源ip地址</span></span><br><span class="line">	<span class="keyword">unsigned</span> <span class="keyword">char</span> DestMacAdd[<span class="number">6</span>]; <span class="comment">//目的mac地址</span></span><br><span class="line">	<span class="keyword">unsigned</span> <span class="keyword">long</span> DestIpAdd; <span class="comment">//目的ip地址</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">//arp包结构</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">ArpPacket</span> &#123;</span></span><br><span class="line">	EthernetHeader ed;</span><br><span class="line">	Arpheader ah;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">sparam</span> &#123;</span></span><br><span class="line">	<span class="keyword">pcap_t</span> *adhandle;</span><br><span class="line">	<span class="keyword">char</span> *ip;</span><br><span class="line">	<span class="keyword">unsigned</span> <span class="keyword">char</span> *mac;</span><br><span class="line">	<span class="keyword">char</span> *netmask;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">gparam</span> &#123;</span></span><br><span class="line">	<span class="keyword">pcap_t</span> *adhandle;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">sparam</span> <span class="title">sp</span>;</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">gparam</span> <span class="title">gp</span>;</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>到现在代码也是完整可以运行的，如果有问题请检查上述代码完整性和位置。 可能出现的BUG： 只显示ARP发送成功，没有接受到并解析打印。可能的原因是帧构造有问题，字节没有对齐，有偏差，像#define一样 写入如下代码：</p>
                  <figure class="highlight cpp">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="meta">#<span class="meta-keyword">pragma</span> pack(1)  <span class="comment">//按一个字节内存对齐</span></span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>GO ON.. 获取到了自身的MAC地址之后，就可以在本机上构建ARP广播请求，向局域网内的所有主机发送ARP请求，得到回应之后解析回应的数据包并进行解析，得到对方的MAC地址。在这里我们需要开启两个线程，一个用来发送一个用来接收。好，我们继续.. 先声明两个线程</p>
                  <figure class="highlight lasso">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="keyword">HANDLE</span> sendthread;      <span class="comment">//发送ARP包线程</span></span><br><span class="line"><span class="keyword">HANDLE</span> recvthread;       <span class="comment">//接受ARP包线程</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>在main方法中继续写，对sp和gp两个ARP请求所需要的结构体进行赋值。赋值什么？就是你之前用ifget获取来的IP地址和子网掩码以及用getSelfMac获取来的MAC地址。</p>
                  <figure class="highlight abnf">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">sp.adhandle = adhandle<span class="comment">;</span></span><br><span class="line">	sp.ip = ip_addr<span class="comment">;</span></span><br><span class="line">	sp.mac = ip_mac<span class="comment">;</span></span><br><span class="line">	sp.netmask = ip_netmask<span class="comment">;</span></span><br><span class="line">	gp.adhandle = adhandle<span class="comment">;</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>接下来直接创建两个线程，一个是发送一个接受，分别调用两个方法。</p>
                  <figure class="highlight lisp">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">sendthread = CreateThread(<span class="name">NULL</span>, <span class="number">0</span>, (<span class="name">LPTHREAD_START_ROUTINE</span>) SendArpPacket,</span><br><span class="line">			<span class="symbol">&amp;sp</span>, <span class="number">0</span>, NULL)<span class="comment">;</span></span><br><span class="line">	recvthread = CreateThread(<span class="name">NULL</span>, <span class="number">0</span>, (<span class="name">LPTHREAD_START_ROUTINE</span>) GetLivePC, <span class="symbol">&amp;gp</span>,</span><br><span class="line">			<span class="number">0</span>, NULL)<span class="comment">;</span></span><br><span class="line">	printf(<span class="string">"\nlistening on 网卡%d ...\n"</span>, i)<span class="comment">;</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>那么发送数据包的方法和接收解析数据包的方法怎样实现呢？ 发送数据包，发送数据包先对结构体数据进行赋值，就像getSelfMac方法一样，然后声明了一个buffer用来存储每一个字节内容。 利用memset方法对buffer进行赋值。再利用一个for循环对255个主机进行发送，指定他们的IP地址。另外定义了一个flag,当发送成功之后将flag设置为1</p>
                  <figure class="highlight cpp">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="comment">/* 向局域网内所有可能的IP地址发送ARP请求包线程 */</span></span><br><span class="line"><span class="function">DWORD WINAPI <span class="title">SendArpPacket</span><span class="params">(LPVOID lpParameter)</span> <span class="comment">//(pcap_t *adhandle,char *ip,unsigned char *mac,char *netmask)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">	sparam *spara = (sparam *) lpParameter;</span><br><span class="line">	<span class="keyword">pcap_t</span> *adhandle = spara-&gt;adhandle;</span><br><span class="line">	<span class="keyword">char</span> *ip = spara-&gt;ip;</span><br><span class="line">	<span class="keyword">unsigned</span> <span class="keyword">char</span> *mac = spara-&gt;mac;</span><br><span class="line">	<span class="keyword">char</span> *netmask = spara-&gt;netmask;</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">"ip_mac:%02x-%02x-%02x-%02x-%02x-%02x\n"</span>, mac[<span class="number">0</span>], mac[<span class="number">1</span>], mac[<span class="number">2</span>],</span><br><span class="line">			mac[<span class="number">3</span>], mac[<span class="number">4</span>], mac[<span class="number">5</span>]);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">"自身的IP地址为:%s\n"</span>, ip);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">"地址掩码NETMASK为:%s\n"</span>, netmask);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">"\n"</span>);</span><br><span class="line">	<span class="keyword">unsigned</span> <span class="keyword">char</span> sendbuf[<span class="number">42</span>]; <span class="comment">//arp包结构大小</span></span><br><span class="line">	EthernetHeader eh;</span><br><span class="line">	Arpheader ah;</span><br><span class="line">	<span class="comment">//赋值MAC地址</span></span><br><span class="line">	<span class="built_in">memset</span>(eh.DestMAC, <span class="number">0xff</span>, <span class="number">6</span>);       <span class="comment">//目的地址为全为广播地址</span></span><br><span class="line">	<span class="built_in">memcpy</span>(eh.SourMAC, mac, <span class="number">6</span>);</span><br><span class="line">	<span class="built_in">memcpy</span>(ah.SourceMacAdd, mac, <span class="number">6</span>);</span><br><span class="line">	<span class="built_in">memset</span>(ah.DestMacAdd, <span class="number">0x00</span>, <span class="number">6</span>);</span><br><span class="line">	eh.EthType = htons(ETH_ARP);</span><br><span class="line">	ah.HardwareType = htons(ARP_HARDWARE);</span><br><span class="line">	ah.ProtocolType = htons(ETH_IP);</span><br><span class="line">	ah.HardwareAddLen = <span class="number">6</span>;</span><br><span class="line">	ah.ProtocolAddLen = <span class="number">4</span>;</span><br><span class="line">	ah.SourceIpAdd = inet_addr(ip); <span class="comment">//请求方的IP地址为自身的IP地址</span></span><br><span class="line">	ah.OperationField = htons(ARP_REQUEST);</span><br><span class="line">	<span class="comment">//向局域网内广播发送arp包</span></span><br><span class="line">	<span class="keyword">unsigned</span> <span class="keyword">long</span> myip = inet_addr(ip);</span><br><span class="line">	<span class="keyword">unsigned</span> <span class="keyword">long</span> mynetmask = inet_addr(netmask);</span><br><span class="line">	<span class="keyword">unsigned</span> <span class="keyword">long</span> hisip = htonl((myip &amp; mynetmask));</span><br><span class="line">	<span class="comment">//向255个主机发送</span></span><br><span class="line">	<span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; HOSTNUM; i++) &#123;</span><br><span class="line">		ah.DestIpAdd = htonl(hisip + i);</span><br><span class="line">		<span class="comment">//构造一个ARP请求</span></span><br><span class="line">		<span class="built_in">memset</span>(sendbuf, <span class="number">0</span>, <span class="keyword">sizeof</span>(sendbuf));</span><br><span class="line">		<span class="built_in">memcpy</span>(sendbuf, &amp;eh, <span class="keyword">sizeof</span>(eh));</span><br><span class="line">		<span class="built_in">memcpy</span>(sendbuf + <span class="keyword">sizeof</span>(eh), &amp;ah, <span class="keyword">sizeof</span>(ah));</span><br><span class="line">		<span class="comment">//如果发送成功</span></span><br><span class="line">		<span class="keyword">if</span> (pcap_sendpacket(adhandle, sendbuf, <span class="number">42</span>) == <span class="number">0</span>) &#123;</span><br><span class="line">			<span class="comment">//printf("\nPacketSend succeed\n");</span></span><br><span class="line">		&#125; <span class="keyword">else</span> &#123;</span><br><span class="line">			<span class="built_in">printf</span>(<span class="string">"PacketSendPacket in getmine Error: %d\n"</span>, GetLastError());</span><br><span class="line">		&#125;</span><br><span class="line">		Sleep(<span class="number">50</span>);</span><br><span class="line">	&#125;</span><br><span class="line">	Sleep(<span class="number">1000</span>);</span><br><span class="line">	flag = TRUE;</span><br><span class="line">	<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>注: 此函数和flag变量在前面别忘了声明一下… 然后是接收数据包并打印MAC地址:</p>
                  <figure class="highlight cpp">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="comment">/* 分析截留的数据包获取活动的主机IP地址 */</span></span><br><span class="line"><span class="function">DWORD WINAPI <span class="title">GetLivePC</span><span class="params">(LPVOID lpParameter)</span> <span class="comment">//(pcap_t *adhandle)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">	gparam *gpara = (gparam *) lpParameter;</span><br><span class="line">	<span class="keyword">pcap_t</span> *adhandle = gpara-&gt;adhandle;</span><br><span class="line">	<span class="keyword">int</span> res;</span><br><span class="line">	<span class="keyword">unsigned</span> <span class="keyword">char</span> Mac[<span class="number">6</span>];</span><br><span class="line">	<span class="class"><span class="keyword">struct</span> <span class="title">pcap_pkthdr</span> * <span class="title">pkt_header</span>;</span></span><br><span class="line">	<span class="keyword">const</span> u_char * pkt_data;</span><br><span class="line">	<span class="keyword">while</span> (<span class="literal">true</span>) &#123;</span><br><span class="line">		<span class="keyword">if</span> (flag) &#123;</span><br><span class="line">			<span class="built_in">printf</span>(<span class="string">"获取MAC地址完毕,请输入你要发送对方的IP地址:\n"</span>);</span><br><span class="line">			<span class="keyword">break</span>;</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="keyword">if</span> ((res = pcap_next_ex(adhandle, &amp;pkt_header, &amp;pkt_data)) &gt;= <span class="number">0</span>) &#123;</span><br><span class="line">			<span class="keyword">if</span> (*(<span class="keyword">unsigned</span> short *) (pkt_data + <span class="number">12</span>) == htons(ETH_ARP)) &#123;</span><br><span class="line">				ArpPacket *recv = (ArpPacket *) pkt_data;</span><br><span class="line">				<span class="keyword">if</span> (*(<span class="keyword">unsigned</span> short *) (pkt_data + <span class="number">20</span>) == htons(ARP_REPLY)) &#123;</span><br><span class="line">					<span class="built_in">printf</span>(<span class="string">"-------------------------------------------\n"</span>);</span><br><span class="line">					<span class="built_in">printf</span>(<span class="string">"IP地址:%d.%d.%d.%d   MAC地址:"</span>,</span><br><span class="line">						     recv-&gt;ah.SourceIpAdd &amp; <span class="number">255</span>,</span><br><span class="line">							 recv-&gt;ah.SourceIpAdd &gt;&gt; <span class="number">8</span> &amp; <span class="number">255</span>,</span><br><span class="line">							 recv-&gt;ah.SourceIpAdd &gt;&gt; <span class="number">16</span> &amp; <span class="number">255</span>,</span><br><span class="line">							 recv-&gt;ah.SourceIpAdd &gt;&gt; <span class="number">24</span> &amp; <span class="number">255</span>);</span><br><span class="line">					<span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; <span class="number">6</span>; i++) &#123;</span><br><span class="line">						Mac[i] = *(<span class="keyword">unsigned</span> <span class="keyword">char</span> *) (pkt_data + <span class="number">22</span> + i);</span><br><span class="line">						<span class="built_in">printf</span>(<span class="string">"%02x"</span>, Mac[i]);</span><br><span class="line">					&#125;</span><br><span class="line">					<span class="built_in">printf</span>(<span class="string">"\n"</span>);</span><br><span class="line">				&#125;</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;</span><br><span class="line">		Sleep(<span class="number">10</span>);</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>以上暂告一段落，通过整合以上代码，我们可以得到如下运行结果：</p>
                  <figure class="highlight asciidoc">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">--------------------------------------------------</span><br><span class="line">number:1</span><br><span class="line">name:rpcap://\Device\NPF<span class="emphasis">_&#123;5AC72F8D-019C-4003-B51B-</span></span><br><span class="line"><span class="emphasis">description:Network adapter 'Microsoft' on local h</span></span><br><span class="line"><span class="emphasis">        Loopback: no</span></span><br><span class="line"><span class="emphasis">Address Family Name:AF_</span>INET6</span><br><span class="line">this is an IPV6 address</span><br><span class="line">Address Family Name:AF<span class="emphasis">_INET6</span></span><br><span class="line"><span class="emphasis">this is an IPV6 address</span></span><br><span class="line"><span class="emphasis">--------------------------------------------------</span></span><br><span class="line"><span class="emphasis">number:2</span></span><br><span class="line"><span class="emphasis">name:rpcap://\Device\NPF_</span>&#123;C17EB3F6-1E86-40E5-8790-</span><br><span class="line">description:Network adapter <span class="emphasis">'Microsoft'</span> on local h</span><br><span class="line"><span class="code">        Loopback: no</span></span><br><span class="line">Address Family Name:AF<span class="emphasis">_INET6</span></span><br><span class="line"><span class="emphasis">this is an IPV6 address</span></span><br><span class="line"><span class="emphasis">Address Family Name:AF_</span>INET</span><br><span class="line">Address:192.168.95.1</span><br><span class="line"><span class="code">        Netmask: 255.255.255.0</span></span><br><span class="line"><span class="code">        Broadcast Address: 255.255.255.255</span></span><br><span class="line">--------------------------------------------------</span><br><span class="line">number:3</span><br><span class="line">name:rpcap://\Device\NPF<span class="emphasis">_&#123;33E23A2F-F791-409B-8452-</span></span><br><span class="line"><span class="emphasis">description:Network adapter 'Qualcomm Atheros Ar81</span></span><br><span class="line"><span class="emphasis">oller' on local host</span></span><br><span class="line"><span class="emphasis">        Loopback: no</span></span><br><span class="line"><span class="emphasis">Address Family Name:AF_</span>INET6</span><br><span class="line">this is an IPV6 address</span><br><span class="line">Address Family Name:AF<span class="emphasis">_INET6</span></span><br><span class="line"><span class="emphasis">this is an IPV6 address</span></span><br><span class="line"><span class="emphasis">Address Family Name:AF_</span>INET6</span><br><span class="line">this is an IPV6 address</span><br><span class="line">Address Family Name:AF<span class="emphasis">_INET</span></span><br><span class="line"><span class="emphasis">Address:121.250.216.237</span></span><br><span class="line"><span class="emphasis">        Netmask: 255.255.255.0</span></span><br><span class="line"><span class="emphasis">        Broadcast Address: 255.255.255.255</span></span><br><span class="line"><span class="emphasis">--------------------------------------------------</span></span><br><span class="line"><span class="emphasis">number:4</span></span><br><span class="line"><span class="emphasis">name:rpcap://\Device\NPF_</span>&#123;DCCF036F-A9A8-4225-B980-</span><br><span class="line">description:Network adapter <span class="emphasis">'Microsoft'</span> on local h</span><br><span class="line"><span class="code">        Loopback: no</span></span><br><span class="line">Address Family Name:AF<span class="emphasis">_INET6</span></span><br><span class="line"><span class="emphasis">this is an IPV6 address</span></span><br><span class="line"><span class="emphasis">Address Family Name:AF_</span>INET6</span><br><span class="line">this is an IPV6 address</span><br><span class="line">--------------------------------------------------</span><br><span class="line">number:5</span><br><span class="line">name:rpcap://\Device\NPF<span class="emphasis">_&#123;D62A0060-F424-46FC-83A5-</span></span><br><span class="line"><span class="emphasis">description:Network adapter 'Microsoft' on local h</span></span><br><span class="line"><span class="emphasis">        Loopback: no</span></span><br><span class="line"><span class="emphasis">Address Family Name:AF_</span>INET6</span><br><span class="line">this is an IPV6 address</span><br><span class="line">Address Family Name:AF<span class="emphasis">_INET</span></span><br><span class="line"><span class="emphasis">Address:192.168.191.1</span></span><br><span class="line"><span class="emphasis">        Netmask: 255.255.255.0</span></span><br><span class="line"><span class="emphasis">        Broadcast Address: 255.255.255.255</span></span><br><span class="line"><span class="emphasis">--------------------------------------------------</span></span><br><span class="line"><span class="emphasis">number:6</span></span><br><span class="line"><span class="emphasis">name:rpcap://\Device\NPF_</span>&#123;B5224A53-8450-4537-AB3B-</span><br><span class="line">description:Network adapter <span class="emphasis">'Microsoft'</span> on local h</span><br><span class="line"><span class="code">        Loopback: no</span></span><br><span class="line">Address Family Name:AF<span class="emphasis">_INET6</span></span><br><span class="line"><span class="emphasis">this is an IPV6 address</span></span><br><span class="line"><span class="emphasis">Address Family Name:AF_</span>INET</span><br><span class="line">Address:192.168.191.2</span><br><span class="line"><span class="code">        Netmask: 255.255.255.0</span></span><br><span class="line"><span class="code">        Broadcast Address: 255.255.255.255</span></span><br><span class="line">Enter the interface number(1-6):3</span><br><span class="line"></span><br><span class="line">ipstr:121.250.216.237</span><br><span class="line">netmask:255.255.255.0</span><br><span class="line"></span><br><span class="line">PacketSend succeed</span><br><span class="line">获取自己主机的MAC地址成功!</span><br><span class="line"></span><br><span class="line">listening on 网卡2 ...</span><br><span class="line">ip<span class="emphasis">_mac:dc-0e-a1-ec-53-c3</span></span><br><span class="line"><span class="emphasis">自身的IP地址为:121.250.216.237</span></span><br><span class="line"><span class="emphasis">地址掩码NETMASK为:255.255.255.0</span></span><br><span class="line"><span class="emphasis"></span></span><br><span class="line"><span class="emphasis">请按任意键继续. . . ------------------------------</span></span><br><span class="line"><span class="emphasis">IP地址:121.250.216.1   MAC地址:000fe28e6100</span></span><br><span class="line"><span class="emphasis">-------------------------------------------</span></span><br><span class="line"><span class="emphasis">IP地址:121.250.216.3   MAC地址:089e012d20d5</span></span><br><span class="line"><span class="emphasis">-------------------------------------------</span></span><br><span class="line"><span class="emphasis">IP地址:121.250.216.5   MAC地址:5404a6af5f2d</span></span><br><span class="line"><span class="emphasis">-------------------------------------------</span></span><br><span class="line"><span class="emphasis">IP地址:121.250.216.6   MAC地址:28d244248d81</span></span><br><span class="line"><span class="emphasis">-------------------------------------------</span></span><br><span class="line"><span class="emphasis">IP地址:121.250.216.7   MAC地址:80fa5b0283f3</span></span><br><span class="line"><span class="emphasis">-------------------------------------------</span></span><br><span class="line"><span class="emphasis">IP地址:121.250.216.8   MAC地址:14dae9005b9e</span></span><br><span class="line"><span class="emphasis">-------------------------------------------</span></span><br><span class="line"><span class="emphasis">IP地址:121.250.216.9   MAC地址:b82a72bf8bce</span></span><br><span class="line"><span class="emphasis">-------------------------------------------</span></span><br><span class="line"><span class="emphasis">IP地址:121.250.216.12   MAC地址:84c9b2fefeed</span></span><br><span class="line"><span class="emphasis">-------------------------------------------</span></span><br><span class="line"><span class="emphasis">IP地址:121.250.216.15   MAC地址:28d2440b4b1b</span></span><br><span class="line"><span class="emphasis">-------------------------------------------</span></span><br><span class="line"><span class="emphasis">IP地址:121.250.216.16   MAC地址:bcee7b969beb</span></span><br><span class="line"><span class="emphasis">-------------------------------------------</span></span><br><span class="line"><span class="emphasis">........此处省略一万字....</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>接下来我们让用户输入要发送的IP地址和要发送的数据</p>
                  <figure class="highlight perl">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">u_int ip1,ip2,ip3,ip4;</span><br><span class="line">		scanf_s(<span class="string">"%d.%d.%d.%d"</span>,&amp;ip1,&amp;ip2,&amp;ip3,&amp;ip4);</span><br><span class="line">		<span class="keyword">printf</span>(<span class="string">"请输入你要发送的内容:\n"</span>);</span><br><span class="line">		getchar();</span><br><span class="line">		gets_s(TcpData);</span><br><span class="line">		<span class="keyword">printf</span>(<span class="string">"要发送的内容:%s\n"</span>,TcpData);</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>声明一下TcpData</p>
                  <figure class="highlight scss">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">char TcpData<span class="selector-attr">[20]</span>;   <span class="comment">//发送内容</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>接下来就是重头戏了，需要声明各种结构体，我们发送的是TCP数据，这样，TCP的TcpData 就作为真正的内容，然后在前面加上TCP头，IP头，帧头，还有校验和要正确。 最后构成一个完整的帧，那么另外声明的结构体如下，前面代码声明过的帧头部结构体就去掉了。</p>
                  <figure class="highlight objectivec">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="comment">//IP地址格式</span></span><br><span class="line"><span class="keyword">struct</span> IpAddress</span><br><span class="line">&#123;</span><br><span class="line">    u_char byte1;</span><br><span class="line">    u_char byte2;</span><br><span class="line">    u_char byte3;</span><br><span class="line">    u_char byte4;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">//帧头部结构体，共14字节</span></span><br><span class="line"><span class="keyword">struct</span> EthernetHeader</span><br><span class="line">&#123;</span><br><span class="line">    u_char DestMAC[<span class="number">6</span>];    <span class="comment">//目的MAC地址 6字节</span></span><br><span class="line">    u_char SourMAC[<span class="number">6</span>];   <span class="comment">//源MAC地址 6字节</span></span><br><span class="line">    u_short EthType;         <span class="comment">//上一层协议类型，如0x0800代表上一层是IP协议，0x0806为arp  2字节</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">//IP头部结构体，共20字节</span></span><br><span class="line"><span class="keyword">struct</span> IpHeader</span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">unsigned</span> <span class="keyword">char</span> Version_HLen;   <span class="comment">//版本信息4位 ，头长度4位 1字节</span></span><br><span class="line">    <span class="keyword">unsigned</span> <span class="keyword">char</span> TOS;                    <span class="comment">//服务类型    1字节</span></span><br><span class="line">    <span class="keyword">short</span> Length;                              <span class="comment">//数据包长度 2字节</span></span><br><span class="line">    <span class="keyword">short</span> Ident;                                 <span class="comment">//数据包标识  2字节</span></span><br><span class="line">    <span class="keyword">short</span> Flags_Offset;                    <span class="comment">//标志3位，片偏移13位  2字节</span></span><br><span class="line">    <span class="keyword">unsigned</span> <span class="keyword">char</span> TTL;                   <span class="comment">//存活时间  1字节</span></span><br><span class="line">    <span class="keyword">unsigned</span> <span class="keyword">char</span> Protocol;          <span class="comment">//协议类型  1字节</span></span><br><span class="line">    <span class="keyword">short</span> Checksum;                       <span class="comment">//首部校验和 2字节</span></span><br><span class="line">	IpAddress SourceAddr;       <span class="comment">//源IP地址   4字节</span></span><br><span class="line">	IpAddress DestinationAddr; <span class="comment">//目的IP地址  4字节</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">//TCP头部结构体，共20字节</span></span><br><span class="line"><span class="keyword">struct</span> TcpHeader</span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">unsigned</span> <span class="keyword">short</span> SrcPort;                        <span class="comment">//源端口号  2字节</span></span><br><span class="line">    <span class="keyword">unsigned</span> <span class="keyword">short</span> DstPort;                        <span class="comment">//目的端口号 2字节</span></span><br><span class="line">    <span class="keyword">unsigned</span> <span class="keyword">int</span> SequenceNum;               <span class="comment">//序号  4字节</span></span><br><span class="line">    <span class="keyword">unsigned</span> <span class="keyword">int</span> Acknowledgment;         <span class="comment">//确认号  4字节</span></span><br><span class="line">    <span class="keyword">unsigned</span> <span class="keyword">char</span> HdrLen;                         <span class="comment">//首部长度4位，保留位6位 共10位</span></span><br><span class="line">    <span class="keyword">unsigned</span> <span class="keyword">char</span> Flags;                              <span class="comment">//标志位6位</span></span><br><span class="line">    <span class="keyword">unsigned</span> <span class="keyword">short</span> AdvertisedWindow;  <span class="comment">//窗口大小16位 2字节</span></span><br><span class="line">    <span class="keyword">unsigned</span> <span class="keyword">short</span> Checksum;                  <span class="comment">//校验和16位   2字节</span></span><br><span class="line">    <span class="keyword">unsigned</span> <span class="keyword">short</span> UrgPtr;						  <span class="comment">//紧急指针16位   2字节</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">//TCP伪首部结构体 12字节</span></span><br><span class="line"><span class="keyword">struct</span> PsdTcpHeader</span><br><span class="line">&#123;</span><br><span class="line">	IpAddress SourceAddr;                     <span class="comment">//源IP地址  4字节</span></span><br><span class="line">	IpAddress DestinationAddr;             <span class="comment">//目的IP地址 4字节</span></span><br><span class="line">    <span class="keyword">char</span> Zero;                                                    <span class="comment">//填充位  1字节</span></span><br><span class="line">    <span class="keyword">char</span> Protcol;                                               <span class="comment">//协议号  1字节</span></span><br><span class="line">    <span class="keyword">unsigned</span> <span class="keyword">short</span> TcpLen;                           <span class="comment">//TCP包长度 2字节</span></span><br><span class="line">&#125;;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>继续main函数中对各种结构体的数据进行初始化赋值，并计算校验和。</p>
                  <figure class="highlight arduino">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="comment">//结构体初始化为0序列</span></span><br><span class="line">		<span class="built_in">memset</span>(&amp;ethernet, <span class="number">0</span>, <span class="keyword">sizeof</span>(ethernet));</span><br><span class="line">		BYTE destmac[<span class="number">8</span>];</span><br><span class="line">		<span class="comment">//目的MAC地址,此处没有对帧的MAC地址进行赋值，因为网卡设置的混杂模式，可以接受经过该网卡的所有帧。当然最好的方法是赋值为ARP刚才获取到的MAC地址，当然不赋值也可以捕捉到并解析，在此处仅做下说明。</span></span><br><span class="line">		destmac[<span class="number">0</span>] = <span class="number">0x00</span>;</span><br><span class="line">		destmac[<span class="number">1</span>] = <span class="number">0x11</span>;</span><br><span class="line">		destmac[<span class="number">2</span>] = <span class="number">0x22</span>;</span><br><span class="line">		destmac[<span class="number">3</span>] = <span class="number">0x33</span>;</span><br><span class="line">		destmac[<span class="number">4</span>] = <span class="number">0x44</span>;</span><br><span class="line">		destmac[<span class="number">5</span>] = <span class="number">0x55</span>;</span><br><span class="line">		<span class="comment">//赋值目的MAC地址</span></span><br><span class="line">		<span class="built_in">memcpy</span>(ethernet.DestMAC, destmac, <span class="number">6</span>);</span><br><span class="line">		BYTE hostmac[<span class="number">8</span>];</span><br><span class="line">		<span class="comment">//源MAC地址</span></span><br><span class="line">		hostmac[<span class="number">0</span>] = <span class="number">0x00</span>;</span><br><span class="line">		hostmac[<span class="number">1</span>] = <span class="number">0x1a</span>;</span><br><span class="line">		hostmac[<span class="number">2</span>] = <span class="number">0x4d</span>;</span><br><span class="line">		hostmac[<span class="number">3</span>] = <span class="number">0x70</span>;</span><br><span class="line">		hostmac[<span class="number">4</span>] = <span class="number">0xa3</span>;</span><br><span class="line">		hostmac[<span class="number">5</span>] = <span class="number">0x89</span>;</span><br><span class="line">		<span class="comment">//赋值源MAC地址</span></span><br><span class="line">		<span class="built_in">memcpy</span>(ethernet.SourMAC, hostmac, <span class="number">6</span>);</span><br><span class="line">		<span class="comment">//上层协议类型,0x0800代表IP协议</span></span><br><span class="line">		ethernet.EthType = htons(<span class="number">0x0800</span>);</span><br><span class="line">		<span class="comment">//赋值SendBuffer</span></span><br><span class="line">		<span class="built_in">memcpy</span>(&amp;SendBuffer, ðernet, <span class="keyword">sizeof</span>(struct EthernetHeader));</span><br><span class="line">		<span class="comment">//赋值IP头部信息</span></span><br><span class="line">		ip.Version_HLen = <span class="number">0x45</span>;</span><br><span class="line">		ip.TOS = <span class="number">0</span>;</span><br><span class="line">		ip.Length = htons(<span class="keyword">sizeof</span>(struct IpHeader) + <span class="keyword">sizeof</span>(struct TcpHeader) + <span class="built_in">strlen</span>(TcpData));</span><br><span class="line">		ip.Ident = htons(<span class="number">1</span>);</span><br><span class="line">		ip.Flags_Offset = <span class="number">0</span>;</span><br><span class="line">		ip.TTL = <span class="number">128</span>;</span><br><span class="line">		ip.Protocol = <span class="number">6</span>;</span><br><span class="line">		ip.Checksum = <span class="number">0</span>;</span><br><span class="line">		<span class="comment">//源IP地址</span></span><br><span class="line">		ip.SourceAddr.byte1 = <span class="number">127</span>;</span><br><span class="line">		ip.SourceAddr.byte2 = <span class="number">0</span>;</span><br><span class="line">		ip.SourceAddr.byte3 = <span class="number">0</span>;</span><br><span class="line">		ip.SourceAddr.byte4 = <span class="number">1</span>;</span><br><span class="line">		<span class="comment">//目的IP地址</span></span><br><span class="line">		ip.DestinationAddr.byte1 = ip1;</span><br><span class="line">		ip.DestinationAddr.byte2 = ip2;</span><br><span class="line">		ip.DestinationAddr.byte3 = ip3;</span><br><span class="line">		ip.DestinationAddr.byte4 = ip4;</span><br><span class="line">		<span class="comment">//赋值SendBuffer</span></span><br><span class="line">		<span class="built_in">memcpy</span>(&amp;SendBuffer[<span class="keyword">sizeof</span>(struct EthernetHeader)], &amp;ip, <span class="number">20</span>);</span><br><span class="line">		<span class="comment">//赋值TCP头部内容</span></span><br><span class="line">		tcp.DstPort = htons(<span class="number">102</span>);</span><br><span class="line">		tcp.SrcPort = htons(<span class="number">1000</span>);</span><br><span class="line">		tcp.SequenceNum = htonl(<span class="number">11</span>);</span><br><span class="line">		tcp.Acknowledgment = <span class="number">0</span>;</span><br><span class="line">		tcp.HdrLen = <span class="number">0x50</span>;</span><br><span class="line">		tcp.Flags = <span class="number">0x18</span>;</span><br><span class="line">		tcp.AdvertisedWindow = htons(<span class="number">512</span>);</span><br><span class="line">		tcp.UrgPtr = <span class="number">0</span>;</span><br><span class="line">		tcp.Checksum = <span class="number">0</span>;</span><br><span class="line">		<span class="comment">//赋值SendBuffer</span></span><br><span class="line">		<span class="built_in">memcpy</span>(&amp;SendBuffer[<span class="keyword">sizeof</span>(struct EthernetHeader) + <span class="number">20</span>], &amp;tcp, <span class="number">20</span>);</span><br><span class="line">		<span class="comment">//赋值伪首部</span></span><br><span class="line">		ptcp.SourceAddr = ip.SourceAddr;</span><br><span class="line">		ptcp.DestinationAddr = ip.DestinationAddr;</span><br><span class="line">		ptcp.Zero = <span class="number">0</span>;</span><br><span class="line">		ptcp.Protcol = <span class="number">6</span>;</span><br><span class="line">		ptcp.TcpLen = htons(<span class="keyword">sizeof</span>(struct TcpHeader) + <span class="built_in">strlen</span>(TcpData));</span><br><span class="line">		<span class="comment">//声明临时存储变量，用来计算校验和</span></span><br><span class="line">		<span class="keyword">char</span> TempBuffer[<span class="number">65535</span>];</span><br><span class="line">		<span class="built_in">memcpy</span>(TempBuffer, &amp;ptcp, <span class="keyword">sizeof</span>(struct PsdTcpHeader));</span><br><span class="line">		<span class="built_in">memcpy</span>(TempBuffer + <span class="keyword">sizeof</span>(struct PsdTcpHeader), &amp;tcp, <span class="keyword">sizeof</span>(struct TcpHeader));</span><br><span class="line">		<span class="built_in">memcpy</span>(TempBuffer + <span class="keyword">sizeof</span>(struct PsdTcpHeader) + <span class="keyword">sizeof</span>(struct TcpHeader), TcpData, <span class="built_in">strlen</span>(TcpData));</span><br><span class="line">		<span class="comment">//计算TCP的校验和</span></span><br><span class="line">		tcp.Checksum = checksum((USHORT*)(TempBuffer), <span class="keyword">sizeof</span>(struct PsdTcpHeader) + <span class="keyword">sizeof</span>(struct TcpHeader) + <span class="built_in">strlen</span>(TcpData));</span><br><span class="line">		<span class="comment">//重新把SendBuffer赋值，因为此时校验和已经改变，赋值新的</span></span><br><span class="line">		<span class="built_in">memcpy</span>(SendBuffer + <span class="keyword">sizeof</span>(struct EthernetHeader) + <span class="keyword">sizeof</span>(struct IpHeader), &amp;tcp, <span class="keyword">sizeof</span>(struct TcpHeader));</span><br><span class="line">		<span class="built_in">memcpy</span>(SendBuffer + <span class="keyword">sizeof</span>(struct EthernetHeader) + <span class="keyword">sizeof</span>(struct IpHeader) + <span class="keyword">sizeof</span>(struct TcpHeader), TcpData, <span class="built_in">strlen</span>(TcpData));</span><br><span class="line">		<span class="comment">//初始化TempBuffer为0序列，存储变量来计算IP校验和</span></span><br><span class="line">		<span class="built_in">memset</span>(TempBuffer, <span class="number">0</span>, <span class="keyword">sizeof</span>(TempBuffer));</span><br><span class="line">		<span class="built_in">memcpy</span>(TempBuffer, &amp;ip, <span class="keyword">sizeof</span>(struct IpHeader));</span><br><span class="line">		<span class="comment">//计算IP校验和</span></span><br><span class="line">		ip.Checksum = checksum((USHORT*)(TempBuffer), <span class="keyword">sizeof</span>(struct IpHeader));</span><br><span class="line">		<span class="comment">//重新把SendBuffer赋值，IP校验和已经改变</span></span><br><span class="line">		<span class="built_in">memcpy</span>(SendBuffer + <span class="keyword">sizeof</span>(struct EthernetHeader), &amp;ip, <span class="keyword">sizeof</span>(struct IpHeader));</span><br><span class="line">		<span class="comment">//发送序列的长度</span></span><br><span class="line">		<span class="keyword">int</span> <span class="built_in">size</span> = <span class="keyword">sizeof</span>(struct EthernetHeader) + <span class="keyword">sizeof</span>(struct IpHeader) + <span class="keyword">sizeof</span>(struct TcpHeader) + <span class="built_in">strlen</span>(TcpData);</span><br><span class="line">		<span class="keyword">int</span> result = pcap_sendpacket(adhandle, SendBuffer,<span class="built_in">size</span>);</span><br><span class="line">		<span class="keyword">if</span> (result != <span class="number">0</span>)</span><br><span class="line">		&#123;</span><br><span class="line">			<span class="built_in">printf</span>(<span class="string">"Send Error!\n"</span>);</span><br><span class="line">		&#125; </span><br><span class="line">		<span class="keyword">else</span></span><br><span class="line">		&#123;</span><br><span class="line">			<span class="built_in">printf</span>(<span class="string">"Send TCP Packet.\n"</span>);</span><br><span class="line">			<span class="built_in">printf</span>(<span class="string">"Dstination Port:%d\n"</span>, ntohs(tcp.DstPort));</span><br><span class="line">			<span class="built_in">printf</span>(<span class="string">"Source Port:%d\n"</span>, ntohs(tcp.SrcPort));</span><br><span class="line">			<span class="built_in">printf</span>(<span class="string">"Sequence:%d\n"</span>, ntohl(tcp.SequenceNum));</span><br><span class="line">			<span class="built_in">printf</span>(<span class="string">"Acknowledgment:%d\n"</span>, ntohl(tcp.Acknowledgment));</span><br><span class="line">			<span class="built_in">printf</span>(<span class="string">"Header Length:%d*4\n"</span>, tcp.HdrLen &gt;&gt; <span class="number">4</span>);</span><br><span class="line">			<span class="built_in">printf</span>(<span class="string">"Flags:0x%0x\n"</span>, tcp.Flags);</span><br><span class="line">			<span class="built_in">printf</span>(<span class="string">"AdvertiseWindow:%d\n"</span>, ntohs(tcp.AdvertisedWindow));</span><br><span class="line">			<span class="built_in">printf</span>(<span class="string">"UrgPtr:%d\n"</span>, ntohs(tcp.UrgPtr));</span><br><span class="line">			<span class="built_in">printf</span>(<span class="string">"Checksum:%u\n"</span>, ntohs(tcp.Checksum));</span><br><span class="line">			<span class="built_in">printf</span>(<span class="string">"Send Successfully!\n"</span>);</span><br><span class="line">		&#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>校验和方法如下：</p>
                  <figure class="highlight objectivec">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="comment">//获得校验和的方法</span></span><br><span class="line"><span class="keyword">unsigned</span> <span class="keyword">short</span> checksum(<span class="keyword">unsigned</span> <span class="keyword">short</span> *data, <span class="keyword">int</span> length)</span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">unsigned</span> <span class="keyword">long</span> temp = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">while</span> (length &gt; <span class="number">1</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        temp +=  *data++;</span><br><span class="line">        length -= <span class="keyword">sizeof</span>(<span class="keyword">unsigned</span> <span class="keyword">short</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (length)</span><br><span class="line">    &#123;</span><br><span class="line">        temp += *(<span class="keyword">unsigned</span> <span class="keyword">short</span>*)data;</span><br><span class="line">    &#125;</span><br><span class="line">    temp = (temp &gt;&gt; <span class="number">16</span>) + (temp &amp;<span class="number">0xffff</span>);</span><br><span class="line">    temp += (temp &gt;&gt; <span class="number">16</span>);</span><br><span class="line">    <span class="keyword">return</span> (<span class="keyword">unsigned</span> <span class="keyword">short</span>)(~temp);</span><br><span class="line">&#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>记得在声明一下这个方法。如果放在main函数前当然就不用声明啦。 另外需要声明的变量有</p>
                  <figure class="highlight cpp">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">EthernetHeader</span> <span class="title">ethernet</span>;</span>    <span class="comment">//以太网帧头</span></span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">IpHeader</span> <span class="title">ip</span>;</span>                            <span class="comment">//IP头</span></span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">TcpHeader</span> <span class="title">tcp</span>;</span>                      <span class="comment">//TCP头</span></span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">PsdTcpHeader</span> <span class="title">ptcp</span>;</span>             <span class="comment">//TCP伪首部</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <figure class="highlight cpp">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="keyword">unsigned</span> <span class="keyword">char</span> SendBuffer[<span class="number">200</span>];       <span class="comment">//发送队列</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>接下来的运行结果：</p>
                  <figure class="highlight angelscript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">获取MAC地址完毕,请输</span><br><span class="line"><span class="number">121.250</span><span class="number">.216</span><span class="number">.112</span></span><br><span class="line">请输入你要发送的内容</span><br><span class="line">what <span class="keyword">is</span> tcp</span><br><span class="line">要发送的内容:what i</span><br><span class="line">Send TCP Packet.</span><br><span class="line">Dstination Port:<span class="number">102</span></span><br><span class="line">Source Port:<span class="number">1000</span></span><br><span class="line">Sequence:<span class="number">11</span></span><br><span class="line">Acknowledgment:<span class="number">0</span></span><br><span class="line">Header Length:<span class="number">5</span>*<span class="number">4</span></span><br><span class="line">Flags:<span class="number">0x18</span></span><br><span class="line">AdvertiseWindow:<span class="number">512</span></span><br><span class="line">UrgPtr:<span class="number">0</span></span><br><span class="line">Checksum:<span class="number">17149</span></span><br><span class="line">Send Successfully!</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>截图如下： <img src="http://img.blog.csdn.net/20141018211905731?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3FjcmU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=""> 好啦，发送帧到此就告一段落啦！如果有疑问请留言。 帧的接收很简单，直接贴源码如下：</p>
                  <figure class="highlight cpp">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdlib.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;pcap.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">char</span> *<span class="title">iptos</span><span class="params">(u_long in)</span></span>;       <span class="comment">//u_long即为 unsigned long</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">packet_handler</span><span class="params">(u_char *param, <span class="keyword">const</span> struct pcap_pkthdr *header, <span class="keyword">const</span> u_char *pkt_data)</span></span>;</span><br><span class="line"><span class="comment">//struct tm *ltime;					//和时间处理有关的变量</span></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">IpAddress</span></span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">    u_char byte1;</span><br><span class="line">    u_char byte2;</span><br><span class="line">    u_char byte3;</span><br><span class="line">    u_char byte4;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">//帧头部结构体，共14字节</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">EthernetHeader</span></span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">    u_char DestMAC[<span class="number">6</span>];    <span class="comment">//目的MAC地址 6字节</span></span><br><span class="line">    u_char SourMAC[<span class="number">6</span>];   <span class="comment">//源MAC地址 6字节</span></span><br><span class="line">    u_short EthType;         <span class="comment">//上一层协议类型，如0x0800代表上一层是IP协议，0x0806为arp  2字节</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">//IP头部结构体，共20字节</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">IpHeader</span></span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">    <span class="keyword">unsigned</span> <span class="keyword">char</span> Version_HLen;   <span class="comment">//版本信息4位 ，头长度4位 1字节</span></span><br><span class="line">    <span class="keyword">unsigned</span> <span class="keyword">char</span> TOS;                    <span class="comment">//服务类型    1字节</span></span><br><span class="line">    short Length;                              <span class="comment">//数据包长度 2字节</span></span><br><span class="line">    short Ident;                                 <span class="comment">//数据包标识  2字节</span></span><br><span class="line">    short Flags_Offset;                    <span class="comment">//标志3位，片偏移13位  2字节</span></span><br><span class="line">    <span class="keyword">unsigned</span> <span class="keyword">char</span> TTL;                    <span class="comment">//存活时间  1字节</span></span><br><span class="line">    <span class="keyword">unsigned</span> <span class="keyword">char</span> Protocol;           <span class="comment">//协议类型  1字节</span></span><br><span class="line">    short Checksum;                        <span class="comment">//首部校验和 2字节</span></span><br><span class="line">    IpAddress SourceAddr;           <span class="comment">//源IP地址   4字节</span></span><br><span class="line">    IpAddress DestinationAddr;   <span class="comment">//目的IP地址  4字节</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">//TCP头部结构体，共20字节</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">TcpHeader</span></span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">    <span class="keyword">unsigned</span> short SrcPort;                        <span class="comment">//源端口号  2字节</span></span><br><span class="line">    <span class="keyword">unsigned</span> short DstPort;                        <span class="comment">//目的端口号 2字节</span></span><br><span class="line">    <span class="keyword">unsigned</span> <span class="keyword">int</span> SequenceNum;               <span class="comment">//序号  4字节</span></span><br><span class="line">    <span class="keyword">unsigned</span> <span class="keyword">int</span> Acknowledgment;         <span class="comment">//确认号  4字节</span></span><br><span class="line">    <span class="keyword">unsigned</span> <span class="keyword">char</span> HdrLen;                         <span class="comment">//首部长度4位，保留位6位 共10位</span></span><br><span class="line">    <span class="keyword">unsigned</span> <span class="keyword">char</span> Flags;                              <span class="comment">//标志位6位</span></span><br><span class="line">    <span class="keyword">unsigned</span> short AdvertisedWindow;  <span class="comment">//窗口大小16位 2字节</span></span><br><span class="line">    <span class="keyword">unsigned</span> short Checksum;                  <span class="comment">//校验和16位   2字节</span></span><br><span class="line">    <span class="keyword">unsigned</span> short UrgPtr;						  <span class="comment">//紧急指针16位   2字节</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">//TCP伪首部结构体 12字节</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">PsdTcpHeader</span></span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">    <span class="keyword">unsigned</span> <span class="keyword">long</span> SourceAddr;                     <span class="comment">//源IP地址  4字节</span></span><br><span class="line">    <span class="keyword">unsigned</span> <span class="keyword">long</span> DestinationAddr;             <span class="comment">//目的IP地址 4字节</span></span><br><span class="line">    <span class="keyword">char</span> Zero;                                                    <span class="comment">//填充位  1字节</span></span><br><span class="line">    <span class="keyword">char</span> Protcol;                                               <span class="comment">//协议号  1字节</span></span><br><span class="line">    <span class="keyword">unsigned</span> short TcpLen;                           <span class="comment">//TCP包长度 2字节</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span>&#123;</span><br><span class="line"></span><br><span class="line">	EthernetHeader *ethernet;    <span class="comment">//以太网帧头</span></span><br><span class="line">    IpHeader *ip;                            <span class="comment">//IP头</span></span><br><span class="line">    TcpHeader *tcp;                      <span class="comment">//TCP头</span></span><br><span class="line">    PsdTcpHeader *ptcp;             <span class="comment">//TCP伪首部</span></span><br><span class="line"></span><br><span class="line">	<span class="keyword">pcap_if_t</span>  * alldevs;       <span class="comment">//所有网络适配器</span></span><br><span class="line">	<span class="keyword">pcap_if_t</span>  *d;					<span class="comment">//选中的网络适配器</span></span><br><span class="line">	<span class="keyword">char</span> errbuf[PCAP_ERRBUF_SIZE];   <span class="comment">//错误缓冲区,大小为256</span></span><br><span class="line">	<span class="keyword">char</span> source[PCAP_ERRBUF_SIZE];</span><br><span class="line">	<span class="keyword">pcap_t</span> *adhandle;           <span class="comment">//捕捉实例,是pcap_open返回的对象</span></span><br><span class="line">	<span class="keyword">int</span> i = <span class="number">0</span>;                            <span class="comment">//适配器计数变量</span></span><br><span class="line">	<span class="class"><span class="keyword">struct</span> <span class="title">pcap_pkthdr</span> *<span class="title">header</span>;</span>    <span class="comment">//接收到的数据包的头部</span></span><br><span class="line">    <span class="keyword">const</span> u_char *pkt_data;			  <span class="comment">//接收到的数据包的内容</span></span><br><span class="line">	<span class="keyword">int</span> res;                                    <span class="comment">//表示是否接收到了数据包</span></span><br><span class="line">	u_int netmask;                       <span class="comment">//过滤时用的子网掩码</span></span><br><span class="line">	<span class="keyword">char</span> packet_filter[] = <span class="string">"tcp"</span>;        <span class="comment">//过滤字符</span></span><br><span class="line">	<span class="class"><span class="keyword">struct</span> <span class="title">bpf_program</span> <span class="title">fcode</span>;</span>                     <span class="comment">//pcap_compile所调用的结构体</span></span><br><span class="line"></span><br><span class="line">	u_int ip_len;                                       <span class="comment">//ip地址有效长度</span></span><br><span class="line">	u_short sport,dport;                        <span class="comment">//主机字节序列</span></span><br><span class="line">	u_char packet[<span class="number">100</span>];                       <span class="comment">//发送数据包目的地址</span></span><br><span class="line">	<span class="keyword">pcap_dumper_t</span> *dumpfile;         <span class="comment">//堆文件</span></span><br><span class="line"></span><br><span class="line">	<span class="comment">//time_t local_tv_sec;				//和时间处理有关的变量</span></span><br><span class="line">    <span class="comment">//char timestr[16];					//和时间处理有关的变量</span></span><br><span class="line"></span><br><span class="line">	</span><br><span class="line">	<span class="comment">//获取本地适配器列表</span></span><br><span class="line">	<span class="keyword">if</span>(pcap_findalldevs_ex(PCAP_SRC_IF_STRING,<span class="literal">NULL</span>,&amp;alldevs,errbuf) == <span class="number">-1</span>)&#123;</span><br><span class="line">		<span class="comment">//结果为-1代表出现获取适配器列表失败</span></span><br><span class="line">		<span class="built_in">fprintf</span>(<span class="built_in">stderr</span>,<span class="string">"Error in pcap_findalldevs_ex:\n"</span>,errbuf);</span><br><span class="line">		<span class="comment">//exit(0)代表正常退出,exit(other)为非正常退出,这个值会传给操作系统</span></span><br><span class="line">		<span class="built_in">exit</span>(<span class="number">1</span>);</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="comment">//打印设备列表信息</span></span><br><span class="line">	<span class="keyword">for</span>(d = alldevs;d !=<span class="literal">NULL</span>;d = d-&gt;next)&#123;</span><br><span class="line">		<span class="built_in">printf</span>(<span class="string">"-----------------------------------------------------------------\nnumber:%d\nname:%s\n"</span>,++i,d-&gt;name);</span><br><span class="line">		<span class="keyword">if</span>(d-&gt;description)&#123;</span><br><span class="line">			<span class="comment">//打印适配器的描述信息</span></span><br><span class="line">			<span class="built_in">printf</span>(<span class="string">"description:%s\n"</span>,d-&gt;description);</span><br><span class="line">		&#125;<span class="keyword">else</span>&#123;</span><br><span class="line">			<span class="comment">//适配器不存在描述信息</span></span><br><span class="line">			<span class="built_in">printf</span>(<span class="string">"description:%s"</span>,<span class="string">"no description\n"</span>);</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="comment">//打印本地环回地址</span></span><br><span class="line">		<span class="built_in">printf</span>(<span class="string">"\tLoopback: %s\n"</span>,(d-&gt;flags &amp; PCAP_IF_LOOPBACK)?<span class="string">"yes"</span>:<span class="string">"no"</span>);</span><br><span class="line">		</span><br><span class="line">		 <span class="keyword">pcap_addr_t</span> *a;       <span class="comment">//网络适配器的地址用来存储变量</span></span><br><span class="line">		 <span class="keyword">for</span>(a = d-&gt;addresses;a;a = a-&gt;next)&#123;</span><br><span class="line">			 <span class="comment">//sa_family代表了地址的类型,是IPV4地址类型还是IPV6地址类型</span></span><br><span class="line">			 <span class="keyword">switch</span> (a-&gt;addr-&gt;sa_family)</span><br><span class="line">			 &#123;</span><br><span class="line">				 <span class="keyword">case</span> AF_INET:  <span class="comment">//代表IPV4类型地址</span></span><br><span class="line">					 <span class="built_in">printf</span>(<span class="string">"Address Family Name:AF_INET\n"</span>);</span><br><span class="line">					 <span class="keyword">if</span>(a-&gt;addr)&#123;</span><br><span class="line">						 <span class="comment">//-&gt;的优先级等同于括号,高于强制类型转换,因为addr为sockaddr类型，对其进行操作须转换为sockaddr_in类型</span></span><br><span class="line">						 <span class="built_in">printf</span>(<span class="string">"Address:%s\n"</span>,iptos(((struct sockaddr_in *)a-&gt;addr)-&gt;sin_addr.s_addr));</span><br><span class="line">					 &#125;</span><br><span class="line">					<span class="keyword">if</span> (a-&gt;netmask)&#123;</span><br><span class="line">						 <span class="built_in">printf</span>(<span class="string">"\tNetmask: %s\n"</span>,iptos(((struct sockaddr_in *)a-&gt;netmask)-&gt;sin_addr.s_addr));</span><br><span class="line">					&#125;</span><br><span class="line">					<span class="keyword">if</span> (a-&gt;broadaddr)&#123;</span><br><span class="line">						   <span class="built_in">printf</span>(<span class="string">"\tBroadcast Address: %s\n"</span>,iptos(((struct sockaddr_in *)a-&gt;broadaddr)-&gt;sin_addr.s_addr));</span><br><span class="line">					 &#125;</span><br><span class="line">					 <span class="keyword">if</span> (a-&gt;dstaddr)&#123;</span><br><span class="line">						   <span class="built_in">printf</span>(<span class="string">"\tDestination Address: %s\n"</span>,iptos(((struct sockaddr_in *)a-&gt;dstaddr)-&gt;sin_addr.s_addr));</span><br><span class="line">					 &#125;</span><br><span class="line">        			 <span class="keyword">break</span>;</span><br><span class="line">				 <span class="keyword">case</span> AF_INET6: <span class="comment">//代表IPV6类型地址</span></span><br><span class="line">					 <span class="built_in">printf</span>(<span class="string">"Address Family Name:AF_INET6\n"</span>);</span><br><span class="line">					 <span class="built_in">printf</span>(<span class="string">"this is an IPV6 address\n"</span>);</span><br><span class="line">					 <span class="keyword">break</span>;</span><br><span class="line">				 <span class="keyword">default</span>:</span><br><span class="line">					 <span class="keyword">break</span>;</span><br><span class="line">			 &#125;</span><br><span class="line">		 &#125;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="comment">//i为0代表上述循环未进入,即没有找到适配器,可能的原因为Winpcap没有安装导致未扫描到</span></span><br><span class="line">	<span class="keyword">if</span>(i == <span class="number">0</span>)&#123;</span><br><span class="line">		<span class="built_in">printf</span>(<span class="string">"interface not found,please check winpcap installation"</span>);</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="keyword">int</span> num;</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">"Enter the interface number(1-%d):"</span>,i);</span><br><span class="line">	<span class="comment">//让用户选择选择哪个适配器进行抓包</span></span><br><span class="line">	scanf_s(<span class="string">"%d"</span>,&amp;num);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">"\n"</span>);</span><br><span class="line"></span><br><span class="line">	<span class="comment">//用户输入的数字超出合理范围</span></span><br><span class="line">	<span class="keyword">if</span>(num&lt;<span class="number">1</span>||num&gt;i)&#123;</span><br><span class="line">		<span class="built_in">printf</span>(<span class="string">"number out of range\n"</span>);</span><br><span class="line">		pcap_freealldevs(alldevs);</span><br><span class="line">		<span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="comment">//跳转到选中的适配器</span></span><br><span class="line">	<span class="keyword">for</span>(d=alldevs, i=<span class="number">0</span>; i&lt; num<span class="number">-1</span> ; d=d-&gt;next, i++);</span><br><span class="line"></span><br><span class="line">	<span class="comment">//运行到此处说明用户的输入是合法的</span></span><br><span class="line">	<span class="keyword">if</span>((adhandle = pcap_open(d-&gt;name,		<span class="comment">//设备名称</span></span><br><span class="line">														<span class="number">65535</span>,       <span class="comment">//存放数据包的内容长度</span></span><br><span class="line">														PCAP_OPENFLAG_PROMISCUOUS,  <span class="comment">//混杂模式</span></span><br><span class="line">														<span class="number">1000</span>,           <span class="comment">//超时时间</span></span><br><span class="line">														<span class="literal">NULL</span>,          <span class="comment">//远程验证</span></span><br><span class="line">														errbuf         <span class="comment">//错误缓冲</span></span><br><span class="line">														)) == <span class="literal">NULL</span>)&#123;</span><br><span class="line">        <span class="comment">//打开适配器失败,打印错误并释放适配器列表</span></span><br><span class="line">		<span class="built_in">fprintf</span>(<span class="built_in">stderr</span>,<span class="string">"\nUnable to open the adapter. %s is not supported by WinPcap\n"</span>, d-&gt;name);</span><br><span class="line">        <span class="comment">// 释放设备列表 </span></span><br><span class="line">        pcap_freealldevs(alldevs);</span><br><span class="line">        <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">	&#125;</span><br><span class="line">	</span><br><span class="line"></span><br><span class="line">	<span class="comment">//打印输出,正在监听中</span></span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">"\nlistening on %s...\n"</span>, d-&gt;description);</span><br><span class="line"></span><br><span class="line">	<span class="comment">//所在网络不是以太网,此处只取这种情况</span></span><br><span class="line">	<span class="keyword">if</span>(pcap_datalink(adhandle) != DLT_EN10MB)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">fprintf</span>(<span class="built_in">stderr</span>,<span class="string">"\nThis program works only on Ethernet networks.\n"</span>);</span><br><span class="line">        <span class="comment">//释放列表</span></span><br><span class="line">        pcap_freealldevs(alldevs);</span><br><span class="line">        <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">	<span class="comment">//先获得地址的子网掩码</span></span><br><span class="line">	<span class="keyword">if</span>(d-&gt;addresses != <span class="literal">NULL</span>)</span><br><span class="line">        <span class="comment">//获得接口第一个地址的掩码 </span></span><br><span class="line">        netmask=((struct sockaddr_in *)(d-&gt;addresses-&gt;netmask))-&gt;sin_addr.S_un.S_addr;</span><br><span class="line">    <span class="keyword">else</span></span><br><span class="line">        <span class="comment">// 如果接口没有地址，那么我们假设一个C类的掩码</span></span><br><span class="line">        netmask=<span class="number">0xffffff</span>;</span><br><span class="line"></span><br><span class="line">	<span class="comment">//pcap_compile()的原理是将高层的布尔过滤表</span></span><br><span class="line">	<span class="comment">//达式编译成能够被过滤引擎所解释的低层的字节码</span></span><br><span class="line">	<span class="keyword">if</span>(pcap_compile(adhandle,	<span class="comment">//适配器处理对象</span></span><br><span class="line">										&amp;fcode,</span><br><span class="line">										packet_filter,   <span class="comment">//过滤ip和UDP</span></span><br><span class="line">										<span class="number">1</span>,                       <span class="comment">//优化标志</span></span><br><span class="line">										netmask           <span class="comment">//子网掩码</span></span><br><span class="line">										)&lt;<span class="number">0</span>)</span><br><span class="line">	&#123;</span><br><span class="line">		<span class="comment">//过滤出现问题</span></span><br><span class="line">		<span class="built_in">fprintf</span>(<span class="built_in">stderr</span>,<span class="string">"\nUnable to compile the packet filter. Check the syntax.\n"</span>);</span><br><span class="line">        <span class="comment">// 释放设备列表</span></span><br><span class="line">        pcap_freealldevs(alldevs);</span><br><span class="line">        <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="comment">//设置过滤器</span></span><br><span class="line">    <span class="keyword">if</span> (pcap_setfilter(adhandle, &amp;fcode)&lt;<span class="number">0</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">fprintf</span>(<span class="built_in">stderr</span>,<span class="string">"\nError setting the filter.\n"</span>);</span><br><span class="line">        <span class="comment">//释放设备列表</span></span><br><span class="line">        pcap_freealldevs(alldevs);</span><br><span class="line">        <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">	<span class="comment">//利用pcap_next_ex来接受数据包</span></span><br><span class="line">	<span class="keyword">while</span>((res = pcap_next_ex(adhandle,&amp;header,&amp;pkt_data))&gt;=<span class="number">0</span>)</span><br><span class="line">	&#123;</span><br><span class="line">		<span class="keyword">if</span>(res ==<span class="number">0</span>)&#123;</span><br><span class="line">			<span class="comment">//返回值为0代表接受数据包超时，重新循环继续接收</span></span><br><span class="line">			<span class="keyword">continue</span>;</span><br><span class="line">		&#125;<span class="keyword">else</span>&#123;</span><br><span class="line">			<span class="comment">//运行到此处代表接受到正常从数据包</span></span><br><span class="line">			<span class="comment">//header为帧的头部</span></span><br><span class="line">			<span class="built_in">printf</span>(<span class="string">"%.6ld len:%d "</span>, header-&gt;ts.tv_usec, header-&gt;len);</span><br><span class="line">			<span class="comment">// 获得IP数据包头部的位置</span></span><br><span class="line">			ip = (IpHeader *) (pkt_data +<span class="number">14</span>);    <span class="comment">//14为以太网帧头部长度</span></span><br><span class="line">			<span class="comment">//获得TCP头部的位置</span></span><br><span class="line">			ip_len = (ip-&gt;Version_HLen &amp; <span class="number">0xf</span>) *<span class="number">4</span>;</span><br><span class="line">			<span class="built_in">printf</span>(<span class="string">"ip_length:%d "</span>,ip_len);</span><br><span class="line">			tcp = (TcpHeader *)((u_char *)ip+ip_len);</span><br><span class="line">			<span class="keyword">char</span> * data;</span><br><span class="line">			 data = (<span class="keyword">char</span> *)((u_char *)tcp+<span class="number">20</span>);</span><br><span class="line">			 <span class="comment">//将网络字节序列转换成主机字节序列</span></span><br><span class="line">			sport = ntohs( tcp-&gt;SrcPort );</span><br><span class="line">			dport = ntohs( tcp-&gt;DstPort );</span><br><span class="line">			<span class="built_in">printf</span>(<span class="string">"srcport:%d desport:%d\n"</span>,sport,dport);</span><br><span class="line">			<span class="built_in">printf</span>(<span class="string">"%d.%d.%d.%d.%d -&gt; %d.%d.%d.%d.%d\n"</span>,</span><br><span class="line">					ip-&gt;SourceAddr.byte1,</span><br><span class="line">					ip-&gt;SourceAddr.byte2,</span><br><span class="line">					ip-&gt;SourceAddr.byte3,</span><br><span class="line">					ip-&gt;SourceAddr.byte4,</span><br><span class="line">				    sport,</span><br><span class="line">				    ip-&gt;DestinationAddr.byte1,</span><br><span class="line">				    ip-&gt;DestinationAddr.byte2,</span><br><span class="line">				    ip-&gt;DestinationAddr.byte3,</span><br><span class="line">				    ip-&gt;DestinationAddr.byte4,</span><br><span class="line">				    dport);</span><br><span class="line">			<span class="built_in">printf</span>(<span class="string">"%s\n"</span>,data);</span><br><span class="line">		&#125;</span><br><span class="line"></span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	</span><br><span class="line">	<span class="comment">//释放网络适配器列表</span></span><br><span class="line">	pcap_freealldevs(alldevs);</span><br><span class="line"></span><br><span class="line">	<span class="comment">/**</span></span><br><span class="line"><span class="comment">	int pcap_loop  ( pcap_t *  p,  </span></span><br><span class="line"><span class="comment">								  int  cnt,  </span></span><br><span class="line"><span class="comment">								  pcap_handler  callback,  </span></span><br><span class="line"><span class="comment">								  u_char *  user   </span></span><br><span class="line"><span class="comment">								 );</span></span><br><span class="line"><span class="comment">     typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,</span></span><br><span class="line"><span class="comment">                 const u_char *);</span></span><br><span class="line"><span class="comment">	*/</span></span><br><span class="line">	<span class="comment">//开始捕获信息,当捕获到数据包时,会自动调用这个函数</span></span><br><span class="line">	<span class="comment">//pcap_loop(adhandle,0,packet_handler,NULL);</span></span><br><span class="line"></span><br><span class="line">	<span class="keyword">int</span> inum;</span><br><span class="line">	scanf_s(<span class="string">"%d"</span>, &amp;inum);</span><br><span class="line"></span><br><span class="line">	<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 每次捕获到数据包时，libpcap都会自动调用这个回调函数 */</span></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">pcap_loop()函数是基于回调的原理来进行数据捕获的，如技术文档所说，这是一种精妙的方法，并且在某些场合下，</span></span><br><span class="line"><span class="comment">它是一种很好的选择。但是在处理回调有时候会并不实用，它会增加程序的复杂度，特别是在多线程的C++程序中</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)</span></span><br><span class="line"><span class="comment">&#123;</span></span><br><span class="line"><span class="comment">    struct tm *ltime = NULL;</span></span><br><span class="line"><span class="comment">    char timestr[16];</span></span><br><span class="line"><span class="comment">    time_t local_tv_sec;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">    // 将时间戳转换成可识别的格式</span></span><br><span class="line"><span class="comment">    local_tv_sec = header-&gt;ts.tv_sec;</span></span><br><span class="line"><span class="comment">    localtime_s(ltime,&amp;local_tv_sec);</span></span><br><span class="line"><span class="comment">    strftime( timestr, sizeof timestr, "%H:%M:%S", ltime);</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">    printf("%s,%.6ld len:%d\n", timestr, header-&gt;ts.tv_usec, header-&gt;len);</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">&#125;</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="comment">/* 将数字类型的IP地址转换成字符串类型的 */</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> IPTOSBUFFERS    12</span></span><br><span class="line"><span class="function"><span class="keyword">char</span> *<span class="title">iptos</span><span class="params">(u_long in)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">char</span> output[IPTOSBUFFERS][<span class="number">3</span>*<span class="number">4</span>+<span class="number">3</span>+<span class="number">1</span>];</span><br><span class="line">    <span class="keyword">static</span> short which;</span><br><span class="line">    u_char *p;</span><br><span class="line"></span><br><span class="line">    p = (u_char *)&amp;in;</span><br><span class="line">    which = (which + <span class="number">1</span> == IPTOSBUFFERS ? <span class="number">0</span> : which + <span class="number">1</span>);</span><br><span class="line">    sprintf_s(output[which], <span class="string">"%d.%d.%d.%d"</span>, p[<span class="number">0</span>], p[<span class="number">1</span>], p[<span class="number">2</span>], p[<span class="number">3</span>]);</span><br><span class="line">    <span class="keyword">return</span> output[which];</span><br><span class="line">&#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p> 运行截图如下 <img src="http://img.blog.csdn.net/20141018212813479?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3FjcmU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=""> <img src="http://img.blog.csdn.net/20141018212943896?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3FjcmU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=""> Thank You 如有问题，欢迎留言~</p>
                  </p>
                </div>
              </div>
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-user"></i>
                  </span>
                  <span class="post-meta-item-text">作者</span>
                  <span><a href="/authors/崔庆才" class="author" itemprop="url" rel="index">崔庆才</a></span>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>
                  <time title="创建时间：2015-07-13 01:14:21" itemprop="dateCreated datePublished" datetime="2015-07-13T01:14:21+08:00">2015-07-13</time>
                </span>
                <span id="/1918.html" class="post-meta-item leancloud_visitors" data-flag-title="Winpcap网络编程五之ARP协议获得MAC表及主机通信" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="fa fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
                <span class="post-meta-item" title="本文字数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-file-word"></i>
                  </span>
                  <span class="post-meta-item-text">本文字数：</span>
                  <span>28k</span>
                </span>
                <span class="post-meta-item" title="阅读时长">
                  <span class="post-meta-item-icon">
                    <i class="far fa-clock"></i>
                  </span>
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                  <span>26 分钟</span>
                </span>
              </div>
            </article>
            <article itemscope itemtype="http://schema.org/Article" class="post-block index" lang="zh-CN">
              <link itemprop="mainEntityOfPage" href="https://cuiqingcai.com/1913.html">
              <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
                <meta itemprop="image" content="/images/avatar.png">
                <meta itemprop="name" content="崔庆才">
                <meta itemprop="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
              </span>
              <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
                <meta itemprop="name" content="静觅">
              </span>
              <header class="post-header">
                <h2 class="post-title" itemprop="name headline">
                  <a class="label"> C/C++ <i class="label-arrow"></i>
                  </a>
                  <a href="/1913.html" class="post-title-link" itemprop="url">Winpcap网络编程四之环境配置，VS配置Winpcap环境</a>
                </h2>
              </header>
              <div class="post-body" itemprop="articleBody">
                <div class="thumb">
                  <img itemprop="contentUrl" class="random">
                </div>
                <div class="excerpt">
                  <p>
                  <p>上一篇我们介绍了Eclipse配置Winpcap环境。但是美中不足的是Eclipse编写Winpcap会出现各种各样神奇的错误… 本文原文地址： <a href="http://blog.csdn.net/cqcre/article/details/40429517" target="_blank" rel="noopener">我的CSDN博客</a> 其实也不是不能用，就是总是报一些函数不能识别的错误，每次不能识别的函数就是因为缺少了各种各样的头文件或者宏定义…让我比较纠结，心中不由得萌生了一个想法，换个环境试试吧，于是VS环境配置就这么神奇的产生了…. 好，接下来我以VS2012为例为大家讲解Winpcap环境配置，其实VS2010，VS2013等等的版本都是通用哒.. 首先你要有一个VS…这不是废话么… 首先，按照 <a href="http://cuiqingcai.com/1906.html">Eclipse配置Winpcap环境</a> 配置好Winpcap和下载好相关的SDK，这里就不再赘述了 好，文件-新建-项目-Win32控制台应用程序，可以修改下面的路径和项目名称，然后确定 <img src="http://img.blog.csdn.net/20141024163401921?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3FjcmU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=""> 接下来就会蹦出一个窗口..点击下一步 <img src="http://img.blog.csdn.net/20141024163542249?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3FjcmU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=""> 下一步，勾选空项目，然后点击确定，空项目一定要勾选，不然会生成一些不必要的文件。 <img src="http://img.blog.csdn.net/20141024163702870?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3FjcmU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=""> 点击完成，现在看到的界面如下： <img src="http://img.blog.csdn.net/20141024163856875?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3FjcmU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=""> 在项目名上右键单击，选择属性 链接器选项卡—输入—附加依赖项中在前面输入ws2_32.lib;wpcap.lib; 两个类库，截图如下 <img src="http://img.blog.csdn.net/20141024164256328?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3FjcmU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=""> C/C++选项卡—-预处理器—-预处理器定义键入HAVE_REMOTE;WPCAP; 如图所示 <img src="http://img.blog.csdn.net/20141024164409203?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3FjcmU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=""> VC++目录，加入你的Winpcap类库路径，文件夹应该叫WpdPack，一个是Include,一个是lib,这是绝对路径，你的可能与我的不一样，截图如下 <img src="http://img.blog.csdn.net/20141024164629073?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3FjcmU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=""> 好了。点击确定，环境就配好啦。 接下来新建一个cpp文件，运行程序就OK了… <img src="http://img.blog.csdn.net/20141024164828671?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3FjcmU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=""> 如有问题，欢迎留言交流</p>
                  </p>
                </div>
              </div>
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-user"></i>
                  </span>
                  <span class="post-meta-item-text">作者</span>
                  <span><a href="/authors/崔庆才" class="author" itemprop="url" rel="index">崔庆才</a></span>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>
                  <time title="创建时间：2015-07-13 01:02:24" itemprop="dateCreated datePublished" datetime="2015-07-13T01:02:24+08:00">2015-07-13</time>
                </span>
                <span id="/1913.html" class="post-meta-item leancloud_visitors" data-flag-title="Winpcap网络编程四之环境配置，VS配置Winpcap环境" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="fa fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
                <span class="post-meta-item" title="本文字数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-file-word"></i>
                  </span>
                  <span class="post-meta-item-text">本文字数：</span>
                  <span>662</span>
                </span>
                <span class="post-meta-item" title="阅读时长">
                  <span class="post-meta-item-icon">
                    <i class="far fa-clock"></i>
                  </span>
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                  <span>1 分钟</span>
                </span>
              </div>
            </article>
            <article itemscope itemtype="http://schema.org/Article" class="post-block index" lang="zh-CN">
              <link itemprop="mainEntityOfPage" href="https://cuiqingcai.com/1906.html">
              <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
                <meta itemprop="image" content="/images/avatar.png">
                <meta itemprop="name" content="崔庆才">
                <meta itemprop="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
              </span>
              <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
                <meta itemprop="name" content="静觅">
              </span>
              <header class="post-header">
                <h2 class="post-title" itemprop="name headline">
                  <a class="label"> C/C++ <i class="label-arrow"></i>
                  </a>
                  <a href="/1906.html" class="post-title-link" itemprop="url">Winpcap网络编程三之环境配置，Eclipse配置Winpcap环境</a>
                </h2>
              </header>
              <div class="post-body" itemprop="articleBody">
                <div class="thumb">
                  <img itemprop="contentUrl" class="random">
                </div>
                <div class="excerpt">
                  <p>
                  <p>大家好，本节为大家带来在Eclipse下配置Winpcap环境，欢迎大家收看。 本文原文地址来自： <a href="http://blog.csdn.net/cqcre/article/details/39754917" target="_blank" rel="noopener">我的CSDN博客</a> 首先，配置Winpcap环境的前提是你必须配置好了Eclipse下的C/C++环境。如果你还没有配置，欢迎大家收看上节内容进行配置。 链接地址： <a href="http://blog.csdn.net/cqcre/article/details/39754251" target="_blank" rel="noopener">Eclipse配置C/C++环境</a> 若链接失效，请自行查看上一篇文章或者百度其他文章。 废话不多说啦，开始我们的Winpcap的配置。</p>
                  <h2 id="Winpcap下载"><a href="#Winpcap下载" class="headerlink" title="Winpcap下载"></a>Winpcap下载</h2>
                  <p>Winpcap官网： <a href="http://www.winpcap.org/" target="_blank" rel="noopener">Winpcap官网</a> Winpcap目前最新版为4.1.3,首先你要下载exe文件并安装，直接双击运行安装即可。 下载地址： <a href="http://www.winpcap.org/install/default.htm" target="_blank" rel="noopener">Winpcap4.1.3.exe</a> 然后你需要下载开发包，首先必须注意的是，目前最新版本是没有开发包的，最新的开发包为4.1.2，先见下图 <img src="http://img.blog.csdn.net/20141003120936027?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3FjcmU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=""> 下面的红色框说明了目前没有提供Winpcap4.1.3的开发包，最新版本的开发包是4.1.2，他可以与4.1.3的Winpcap配套使用。 所以下载4.1.2的开发包。 下载地址： <a href="http://www.winpcap.org/devel.htm" target="_blank" rel="noopener">Winpcap Developer’s Pack 4.1.2</a></p>
                  <h2 id="Eclipse相关配置"><a href="#Eclipse相关配置" class="headerlink" title="Eclipse相关配置"></a>Eclipse相关配置</h2>
                  <p>首先新建一个C 的项目，具体的建立过程可以参见上一节的内容。 我们加入一个测试代码如下：</p>
                  <figure class="highlight cpp">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="meta">#<span class="meta-keyword">define</span> WIN32</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> HAVE_REMOTE</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">"pcap.h"</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">"Win32-Extensions.h"</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">gen_packet</span><span class="params">(<span class="keyword">unsigned</span> <span class="keyword">char</span> *buf,<span class="keyword">int</span> len)</span></span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">/*生成数据包*/</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">gen_packet</span><span class="params">(<span class="keyword">unsigned</span> <span class="keyword">char</span> *buf,<span class="keyword">int</span> len)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">		<span class="keyword">int</span> i=<span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">		<span class="comment">//设置目标MAC地址为01:01:01:01:01:01</span></span><br><span class="line">		<span class="keyword">for</span> (i=<span class="number">0</span>;i&lt;<span class="number">6</span>;i++)</span><br><span class="line">		&#123;</span><br><span class="line">			buf[i]=<span class="number">0x01</span>;</span><br><span class="line">		&#125;</span><br><span class="line"></span><br><span class="line">		<span class="comment">//设置源MAC地址为02:02:02:02:02:02</span></span><br><span class="line">		<span class="keyword">for</span> (i=<span class="number">6</span>;i&lt;<span class="number">12</span>;i++)</span><br><span class="line">		&#123;</span><br><span class="line">			buf[i]=<span class="number">0x02</span>;</span><br><span class="line">		&#125;</span><br><span class="line"></span><br><span class="line">		<span class="comment">//设置协议标识为0xc0xd，无任何实际意义</span></span><br><span class="line">		buf[<span class="number">12</span>]=<span class="number">0xc</span>;</span><br><span class="line">		buf[<span class="number">13</span>]=<span class="number">0xd</span>;</span><br><span class="line"></span><br><span class="line">		<span class="comment">//填充数据包的内容</span></span><br><span class="line">		<span class="keyword">for</span>(i=<span class="number">14</span>;i&lt;len;i++)</span><br><span class="line">		&#123;</span><br><span class="line">			buf[i]=i<span class="number">-14</span>;</span><br><span class="line">		&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">	<span class="keyword">pcap_if_t</span> *alldevs;</span><br><span class="line">	<span class="keyword">pcap_if_t</span> *d;</span><br><span class="line">	<span class="keyword">int</span> inum;</span><br><span class="line">	<span class="keyword">int</span> i=<span class="number">0</span>;</span><br><span class="line">	<span class="keyword">pcap_t</span> *adhandle;</span><br><span class="line">	<span class="keyword">char</span> errbuf[PCAP_ERRBUF_SIZE];</span><br><span class="line">	<span class="keyword">int</span> ret=<span class="number">-1</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* 获取本机网络设备列表 */</span></span><br><span class="line">    <span class="keyword">if</span> (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, <span class="literal">NULL</span>, &amp;alldevs, errbuf) == <span class="number">-1</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">fprintf</span>(<span class="built_in">stderr</span>,<span class="string">"Error in pcap_findalldevs: %s\n"</span>, errbuf);</span><br><span class="line">        <span class="built_in">exit</span>(<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* 打印网络设备列表 */</span></span><br><span class="line">    <span class="keyword">for</span>(d=alldevs; d; d=d-&gt;next)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">"%d. %s"</span>, ++i, d-&gt;name);</span><br><span class="line">        <span class="keyword">if</span> (d-&gt;description)</span><br><span class="line">            <span class="built_in">printf</span>(<span class="string">" (%s)\n"</span>, d-&gt;description);</span><br><span class="line">        <span class="keyword">else</span></span><br><span class="line">            <span class="built_in">printf</span>(<span class="string">" (No description available)\n"</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span>(i==<span class="number">0</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">"\nNo interfaces found! Make sure WinPcap is installed.\n"</span>);</span><br><span class="line">        <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/*选择网络设备接口*/</span></span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"Enter the interface number (1-%d):"</span>,i);</span><br><span class="line">    <span class="built_in">scanf</span>(<span class="string">"%d"</span>, &amp;inum);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span>(inum &lt; <span class="number">1</span> || inum &gt; i)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">"\nInterface number out of range.\n"</span>);</span><br><span class="line">        <span class="comment">/* 释放设备列表 */</span></span><br><span class="line">        pcap_freealldevs(alldevs);</span><br><span class="line">        <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* 跳转到选中的适配器 */</span></span><br><span class="line">    <span class="keyword">for</span>(d=alldevs, i=<span class="number">0</span>; i&lt; inum<span class="number">-1</span> ;d=d-&gt;next, i++);</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* 打开设备 */</span></span><br><span class="line">    <span class="keyword">if</span> ( (adhandle= pcap_open(d-&gt;name,          <span class="comment">// 设备名</span></span><br><span class="line">							  <span class="number">65536</span>,            <span class="comment">// 65535保证能捕获到数据链路层上每个数据包的全部内容</span></span><br><span class="line">							  PCAP_OPENFLAG_PROMISCUOUS,    <span class="comment">// 混杂模式</span></span><br><span class="line">                              <span class="number">1000</span>,             <span class="comment">// 读取超时时间</span></span><br><span class="line">                              <span class="literal">NULL</span>,             <span class="comment">// 远程机器验证</span></span><br><span class="line">                              errbuf            <span class="comment">// 错误缓冲池</span></span><br><span class="line">                              ) ) == <span class="literal">NULL</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">fprintf</span>(<span class="built_in">stderr</span>,<span class="string">"\nUnable to open the adapter. %s is not supported by WinPcap\n"</span>, d-&gt;name);</span><br><span class="line">        <span class="comment">/* 释放设备列表 */</span></span><br><span class="line">        pcap_freealldevs(alldevs);</span><br><span class="line">        <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/*在选中的设备接口上发送数据*/</span></span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"\nsending on %s...\n"</span>, d-&gt;description);</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* 发送数据包*/</span></span><br><span class="line">	<span class="comment">//生成数据报</span></span><br><span class="line">	<span class="keyword">int</span> packetlen=<span class="number">100</span>;</span><br><span class="line">	<span class="keyword">unsigned</span> <span class="keyword">char</span> *buf= (<span class="keyword">unsigned</span> <span class="keyword">char</span> *)<span class="built_in">malloc</span>(packetlen);</span><br><span class="line">	<span class="built_in">memset</span>(buf,<span class="number">0x0</span>,packetlen);</span><br><span class="line">	gen_packet(buf,packetlen); <span class="comment">//获得生成的数据包，长度为packetlen</span></span><br><span class="line">	<span class="comment">//开始数据包发送</span></span><br><span class="line">	<span class="keyword">if</span> ( (ret=pcap_sendpacket(adhandle,buf,packetlen))==<span class="number">-1</span>)</span><br><span class="line">	&#123;</span><br><span class="line">		<span class="built_in">printf</span>(<span class="string">"发送失败\n"</span>);</span><br><span class="line">		<span class="built_in">free</span>(buf);</span><br><span class="line">		pcap_close(adhandle);</span><br><span class="line">        pcap_freealldevs(alldevs);</span><br><span class="line">        <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	 <span class="comment">/*释放资源*/</span></span><br><span class="line">	 <span class="built_in">free</span>(buf);</span><br><span class="line">	 pcap_close(adhandle);</span><br><span class="line">	 pcap_freealldevs(alldevs);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>把代码拷贝到你的项目程序里面，可以发现现在是编译错误，有些对象根本无法识别，截图如下： <img src="http://img.blog.csdn.net/20141003121756538?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3FjcmU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=""> 接下来就需要我们对类库进行配置啦。 首先解压你下载的开发包，随便放硬盘的某个位置，我放在了D盘的eclipse_plugins文件夹中，当然你可以随便放哪里都行。 <img src="http://img.blog.csdn.net/20141003122134034?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3FjcmU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=""> 接下来配置Eclipse，右键项目-&gt;属性-&gt;C/C++常规-&gt;项目和符号。 <img src="http://img.blog.csdn.net/20141003122332235?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3FjcmU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=""> 首先添加你的include库，在包含这个选项卡中添加你的库，点击添加-&gt;选择文件系统-&gt;选择你刚才的开发库的include文件夹，按照图中的顺序来 <img src="http://img.blog.csdn.net/20141003122614796?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3FjcmU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=""> <img src="http://img.blog.csdn.net/20141003122856279?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3FjcmU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=""> 点击确定添加，同理在库路径选项卡中进行库路径的配置，这次添加的是lib文件夹。按照图片中的顺序来做 <img src="http://img.blog.csdn.net/20141003123234570?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3FjcmU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=""> <img src="http://img.blog.csdn.net/20141003123311433?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3FjcmU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=""> 点击确定添加。 然后在库的选项卡中添加wpcap和Packet两个库，注意这次不能选择文件系统了，因为你指定了库路径之后它会自动搜索路径中库的名字，这次你只需要指定库的名字就好了。我之前添加的是文件系统，然后它总是提示找不到这个库，所以一定要直接填写这两个库的名字。如图所示： <img src="http://img.blog.csdn.net/20141003123715375?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3FjcmU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=""> 添加完毕之后，出现这个样子： <img src="http://img.blog.csdn.net/20141003123823109?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3FjcmU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=""> 好啦，点击确定，全部配置已经完毕啦。 重新构建项目，运行即可。 注意，构建过程可能出现如下问题：</p>
                  <ul>
                    <li>error C2065: “PCAP_SRC_IF_STRING”: 未声明的标识符</li>
                    <li>error C3861: “pcap_findalldevs_ex”: 找不到标识符</li>
                    <li>error C2065: “PCAP_OPENFLAG_PROMISCUOUS”: 未声明的标识符</li>
                    <li>error C3861: “pcap_open”: 找不到标识符</li>
                  </ul>
                  <p>因为新的版本里WinPcap支持远程数据包获取，所以还应当添加一个头文件remote-ext.h ，即#include “remote-ext.h”（记住这条语句要放在#include “pcap.h”之后，否则会出错！） <img src="http://img.blog.csdn.net/20141003124531280?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3FjcmU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=""> 好了，一切问题都解决了，运行成功啦！ 运行结果如下： <img src="http://img.blog.csdn.net/20141003124547093?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3FjcmU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=""> 再附测试代码一例：</p>
                  <figure class="highlight cpp">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="meta">#<span class="meta-keyword">define</span> WIN32</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> HAVE_REMOTE</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">"pcap.h"</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">"Win32-Extensions.h"</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">gen_packet</span><span class="params">(<span class="keyword">unsigned</span> <span class="keyword">char</span> *buf,<span class="keyword">int</span> len)</span></span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">/*生成数据包*/</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">gen_packet</span><span class="params">(<span class="keyword">unsigned</span> <span class="keyword">char</span> *buf,<span class="keyword">int</span> len)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">		<span class="keyword">int</span> i=<span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">		<span class="comment">//设置目标MAC地址为01:01:01:01:01:01</span></span><br><span class="line">		<span class="keyword">for</span> (i=<span class="number">0</span>;i&lt;<span class="number">6</span>;i++)</span><br><span class="line">		&#123;</span><br><span class="line">			buf[i]=<span class="number">0x01</span>;</span><br><span class="line">		&#125;</span><br><span class="line"></span><br><span class="line">		<span class="comment">//设置源MAC地址为02:02:02:02:02:02</span></span><br><span class="line">		<span class="keyword">for</span> (i=<span class="number">6</span>;i&lt;<span class="number">12</span>;i++)</span><br><span class="line">		&#123;</span><br><span class="line">			buf[i]=<span class="number">0x02</span>;</span><br><span class="line">		&#125;</span><br><span class="line"></span><br><span class="line">		<span class="comment">//设置协议标识为0xc0xd，无任何实际意义</span></span><br><span class="line">		buf[<span class="number">12</span>]=<span class="number">0xc</span>;</span><br><span class="line">		buf[<span class="number">13</span>]=<span class="number">0xd</span>;</span><br><span class="line"></span><br><span class="line">		<span class="comment">//填充数据包的内容</span></span><br><span class="line">		<span class="keyword">for</span>(i=<span class="number">14</span>;i&lt;len;i++)</span><br><span class="line">		&#123;</span><br><span class="line">			buf[i]=i<span class="number">-14</span>;</span><br><span class="line">		&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">	<span class="keyword">pcap_if_t</span> *alldevs;</span><br><span class="line">	<span class="keyword">pcap_if_t</span> *d;</span><br><span class="line">	<span class="keyword">int</span> inum;</span><br><span class="line">	<span class="keyword">int</span> i=<span class="number">0</span>;</span><br><span class="line">	<span class="keyword">pcap_t</span> *adhandle;</span><br><span class="line">	<span class="keyword">char</span> errbuf[PCAP_ERRBUF_SIZE];</span><br><span class="line">	<span class="keyword">int</span> ret=<span class="number">-1</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* 获取本机网络设备列表 */</span></span><br><span class="line">    <span class="keyword">if</span> (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, <span class="literal">NULL</span>, &amp;alldevs, errbuf) == <span class="number">-1</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">fprintf</span>(<span class="built_in">stderr</span>,<span class="string">"Error in pcap_findalldevs: %s\n"</span>, errbuf);</span><br><span class="line">        <span class="built_in">exit</span>(<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* 打印网络设备列表 */</span></span><br><span class="line">    <span class="keyword">for</span>(d=alldevs; d; d=d-&gt;next)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">"%d. %s"</span>, ++i, d-&gt;name);</span><br><span class="line">        <span class="keyword">if</span> (d-&gt;description)</span><br><span class="line">            <span class="built_in">printf</span>(<span class="string">" (%s)\n"</span>, d-&gt;description);</span><br><span class="line">        <span class="keyword">else</span></span><br><span class="line">            <span class="built_in">printf</span>(<span class="string">" (No description available)\n"</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span>(i==<span class="number">0</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">"\nNo interfaces found! Make sure WinPcap is installed.\n"</span>);</span><br><span class="line">        <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/*选择网络设备接口*/</span></span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"Enter the interface number (1-%d):"</span>,i);</span><br><span class="line">    <span class="built_in">scanf</span>(<span class="string">"%d"</span>, &amp;inum);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span>(inum &lt; <span class="number">1</span> || inum &gt; i)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">"\nInterface number out of range.\n"</span>);</span><br><span class="line">        <span class="comment">/* 释放设备列表 */</span></span><br><span class="line">        pcap_freealldevs(alldevs);</span><br><span class="line">        <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* 跳转到选中的适配器 */</span></span><br><span class="line">    <span class="keyword">for</span>(d=alldevs, i=<span class="number">0</span>; i&lt; inum<span class="number">-1</span> ;d=d-&gt;next, i++);</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* 打开设备 */</span></span><br><span class="line">    <span class="keyword">if</span> ( (adhandle= pcap_open(d-&gt;name,          <span class="comment">// 设备名</span></span><br><span class="line">							  <span class="number">65536</span>,            <span class="comment">// 65535保证能捕获到数据链路层上每个数据包的全部内容</span></span><br><span class="line">							  PCAP_OPENFLAG_PROMISCUOUS,    <span class="comment">// 混杂模式</span></span><br><span class="line">                              <span class="number">1000</span>,             <span class="comment">// 读取超时时间</span></span><br><span class="line">                              <span class="literal">NULL</span>,             <span class="comment">// 远程机器验证</span></span><br><span class="line">                              errbuf            <span class="comment">// 错误缓冲池</span></span><br><span class="line">                              ) ) == <span class="literal">NULL</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">fprintf</span>(<span class="built_in">stderr</span>,<span class="string">"\nUnable to open the adapter. %s is not supported by WinPcap\n"</span>, d-&gt;name);</span><br><span class="line">        <span class="comment">/* 释放设备列表 */</span></span><br><span class="line">        pcap_freealldevs(alldevs);</span><br><span class="line">        <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/*在选中的设备接口上发送数据*/</span></span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"\nsending on %s...\n"</span>, d-&gt;description);</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* 发送数据包*/</span></span><br><span class="line">	<span class="comment">//生成数据报</span></span><br><span class="line">	<span class="keyword">int</span> packetlen=<span class="number">100</span>;</span><br><span class="line">	<span class="keyword">unsigned</span> <span class="keyword">char</span> *buf= (<span class="keyword">unsigned</span> <span class="keyword">char</span> *)<span class="built_in">malloc</span>(packetlen);</span><br><span class="line">	<span class="built_in">memset</span>(buf,<span class="number">0x0</span>,packetlen);</span><br><span class="line">	gen_packet(buf,packetlen); <span class="comment">//获得生成的数据包，长度为packetlen</span></span><br><span class="line">	<span class="comment">//开始数据包发送</span></span><br><span class="line">	<span class="keyword">if</span> ( (ret=pcap_sendpacket(adhandle,buf,packetlen))==<span class="number">-1</span>)</span><br><span class="line">	&#123;</span><br><span class="line">		<span class="built_in">printf</span>(<span class="string">"发送失败\n"</span>);</span><br><span class="line">		<span class="built_in">free</span>(buf);</span><br><span class="line">		pcap_close(adhandle);</span><br><span class="line">        pcap_freealldevs(alldevs);</span><br><span class="line">        <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	 <span class="comment">/*释放资源*/</span></span><br><span class="line">	 <span class="built_in">free</span>(buf);</span><br><span class="line">	 pcap_close(adhandle);</span><br><span class="line">	 pcap_freealldevs(alldevs);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>运行结果：</p>
                  <figure class="highlight maxima">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="number">1</span>. rpcap://\Device\NPF_&#123;5AC72F8D-<span class="number">019C</span>-<span class="number">4003</span>-B51B-7ABB67AF392A&#125; (Network adapter 'Microsoft' on <span class="built_in">local</span> host)</span><br><span class="line"><span class="number">2</span>. rpcap://\Device\NPF_&#123;33E23A2F-F791-<span class="number">409B-8452</span>-A3FB5A78B73E&#125; (Network adapter 'Qualcomm Atheros Ar81xx series PCI-E Ethernet Controller' on <span class="built_in">local</span> host)</span><br><span class="line"><span class="number">3</span>. rpcap://\Device\NPF_&#123;DCCF036F-A9A8-<span class="number">4225</span>-B980-D3A3F0575F5B&#125; (Network adapter 'Microsoft' on <span class="built_in">local</span> host)</span><br><span class="line"><span class="number">4</span>. rpcap://\Device\NPF_&#123;D62A0060-F424-46FC-83A5-3394081685FD&#125; (Network adapter 'Microsoft' on <span class="built_in">local</span> host)</span><br><span class="line"><span class="number">5</span>. rpcap://\Device\NPF_&#123;B5224A53-<span class="number">8450</span>-<span class="number">4537</span>-AB3B-9869158121CD&#125; (Network adapter 'Microsoft' on <span class="built_in">local</span> host)</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>那么环境配好了，我们接下来就要进行计算机网络编程学习阶段了，后期的文章将会记录我计算机网络编程学习的一些内容，欢迎大家收看。</p>
                  </p>
                </div>
              </div>
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-user"></i>
                  </span>
                  <span class="post-meta-item-text">作者</span>
                  <span><a href="/authors/崔庆才" class="author" itemprop="url" rel="index">崔庆才</a></span>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>
                  <time title="创建时间：2015-07-13 00:54:24" itemprop="dateCreated datePublished" datetime="2015-07-13T00:54:24+08:00">2015-07-13</time>
                </span>
                <span id="/1906.html" class="post-meta-item leancloud_visitors" data-flag-title="Winpcap网络编程三之环境配置，Eclipse配置Winpcap环境" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="fa fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
                <span class="post-meta-item" title="本文字数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-file-word"></i>
                  </span>
                  <span class="post-meta-item-text">本文字数：</span>
                  <span>6.5k</span>
                </span>
                <span class="post-meta-item" title="阅读时长">
                  <span class="post-meta-item-icon">
                    <i class="far fa-clock"></i>
                  </span>
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                  <span>6 分钟</span>
                </span>
              </div>
            </article>
            <article itemscope itemtype="http://schema.org/Article" class="post-block index" lang="zh-CN">
              <link itemprop="mainEntityOfPage" href="https://cuiqingcai.com/1898.html">
              <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
                <meta itemprop="image" content="/images/avatar.png">
                <meta itemprop="name" content="崔庆才">
                <meta itemprop="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
              </span>
              <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
                <meta itemprop="name" content="静觅">
              </span>
              <header class="post-header">
                <h2 class="post-title" itemprop="name headline">
                  <a class="label"> C/C++ <i class="label-arrow"></i>
                  </a>
                  <a href="/1898.html" class="post-title-link" itemprop="url">Winpcap网络编程二之环境配置，Eclipse配置C/C++环境</a>
                </h2>
              </header>
              <div class="post-body" itemprop="articleBody">
                <div class="thumb">
                  <img itemprop="contentUrl" class="random">
                </div>
                <div class="excerpt">
                  <p>
                  <p>本次为大家带来的是用Eclipse配置C/C++环境的具体步骤，希望对大家有帮助哦。 <strong>声明：如果你希望用Eclipse开发，可以参考本文章配置环境，如若想用VS开发，请看后面的文章。</strong> 本文原文地址来自 <a href="http://blog.csdn.net/cqcre/article/details/39754251" target="_blank" rel="noopener">我的CSDN博客</a> Eclipse 配置C/C++开发环境讲解</p>
                  <h2 id="JDK"><a href="#JDK" class="headerlink" title="JDK"></a>JDK</h2>
                  <p>如果没有安装JDK环境的小伙伴请自行去官网下载安装啦，安装之后的就可以跳过此步. 下载地址： <a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html" target="_blank" rel="noopener">JDK下载</a><a href="http://jingyan.baidu.com/article/6dad5075d1dc40a123e36ea3.html" target="_blank" rel="noopener">JDK环境配置</a></p>
                  <h2 id="Eclipse"><a href="#Eclipse" class="headerlink" title="Eclipse"></a>Eclipse</h2>
                  <p>当然，下载JDK的目的是在Eclipse下先运行起Java程序，这样才能方便我们下一步的操作，没有Eclipse的也去下载。 下载地址： <a href="http://www.eclipse.org/downloads/download.php?file=/eclipse/downloads/drops/R-3.7-201106131736/eclipse-SDK-3.7-win32.zip" target="_blank" rel="noopener">Eclipse下载</a> 上面两步我想难度都很小，而且大部分同学已经配置了，我就不一一讲解了。</p>
                  <h2 id="CDT"><a href="#CDT" class="headerlink" title="CDT"></a>CDT</h2>
                  <p>CDT是什么？它就是Eclipse的一个插件，我们需要安装了之后才可以新建C/C++项目。 注意：下载的CDT必须和Eclipse的版本对应。 下载地址： <a href="http://www.eclipse.org/cdt/" target="_blank" rel="noopener">CDT下载</a> 上面下载的Eclipse是3.7版本，在此给出适配CDT 8.0的下载链接。 下载地址： <a href="http://www.eclipse.org/downloads/download.php?file=/tools/cdt/releases/indigo/dist/cdt-master-8.0.0.zip&amp;url=http://mirrors.ustc.edu.cn/eclipse/tools/cdt/releases/indigo/dist/cdt-master-8.0.0.zip&amp;mirror_id=1093" target="_blank" rel="noopener">CDT 8.0下载</a> 如果上述链接已失效，请自行百度适配你Eclipse版本的CDT进行下载。 下载之后它是一个压缩包zip格式。 不要解压直接安装即可，安装讲解如下： 打开Eclipse，进入菜单Help，选择Install New Software…，点击右边Add按钮，在Add Repository对话框中点击右下角的Archive…，浏览到你之前下载保存路径，选中cdt-master-8.0.0.zip并双击，勾选所有CDT部件，然后点击Next&gt;，继续Next&gt;，选中“I accept the terms of the license agreement – Finish”，点击Finish开始安装CDT。 <img src="http://img.blog.csdn.net/20141003110738384?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3FjcmU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=""> 安装完CDT后重启Eclipse。 <img src="http://img.blog.csdn.net/20141003110647109?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3FjcmU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=""> 这样我们的Eclipse的CDT插件就安装好啦，这时你会发现可以新建C/C++项目了，但是还是不能编译运行，为什么？因为没有安装编译器。接下来我们需要下载mingw编译器。</p>
                  <h2 id="MinGW"><a href="#MinGW" class="headerlink" title="MinGW"></a>MinGW</h2>
                  <p>这是一个配套Eclipse的C/C++编译器，首先我们下载下来。 官网下载地址： <a href="http://sourceforge.net/projects/mingw/files/MinGW/" target="_blank" rel="noopener">mingw官网下载</a> 现在发现最新版本下载是： <a href="http://sourceforge.net/projects/mingw/files/latest/download?source=files" target="_blank" rel="noopener">mingw-get-setup.exe</a> 双击运行，选择安装路径，我的路径为：D:\mingw，安装完成之后你会发现出现一个下载库的窗口，叫Mingw Installation Manager 注意： 1. 我的类库已经安装完毕，所以每个类库前面都显示为绿色的方框，没安装之前是白色的，你需要都勾选上，然后下载安装。在每个类库上邮件单击选择make for installation即可勾选。再点击菜单中的Installation中的Update Catalogue即可安装你所勾选的类库了。 2. 安装下载可能花费不少时间，请耐心等待。 <img src="http://img.blog.csdn.net/20141003111834646?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3FjcmU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=""> 大家可以发现最左边有Basic Steup和All Packages两个分类。 第一个Basic Steup即为必须要安装的编译类库，All Packages即为所有的类库。为了保险起见，我把所有的类库都安装了。全部安装完之后即会显示绿色。 安装完之后的目录结构如下： <img src="http://img.blog.csdn.net/20141003112632413?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3FjcmU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=""></p>
                  <h2 id="环境变量配置"><a href="#环境变量配置" class="headerlink" title="环境变量配置"></a>环境变量配置</h2>
                  <p>环境变量配置： 计算机– 属性 – 高级系统设置 – 环境变量 在上方的用户变量中进行如下操作： 注意：mingw的位置不同，环境变量的配置不同，可以看最底层目录比对着来配置。我的环境变量配置如下：</p>
                  <blockquote>
                    <p>（1）编辑PATH变量，在最后面加入 D:\mingw\bin D:\mingw\msys\1.0\bin D:\mingw\mingw32\bin （2）添加LIBRARY_PATH变量，内容为： D:\mingw\lib （3）添加C_INCLUDE_PATH变量，内容为： D:\mingw\include （4）添加CPLUS_INCLUDE_PATH变量，内容为： D:\mingw\lib\gcc\mingw32\4.8.1\include\c++</p>
                  </blockquote>
                  <p>修改：</p>
                  <blockquote>
                    <p>进入D:\mingw\bin下将mingw32-make.exe复制成make.exe。因为Eclipse使用时预设是用系统里的”make”这个文件名，而不是”mingw32-make”。</p>
                  </blockquote>
                  <p>Eclipse中的配置： 窗口 -&gt; 首选项 -&gt; C/C++ -&gt; New CDT Project Wizard 在右边的首选工具链的右边，工具链栏目内选择MinGW GCC，确定，如图所示： <img src="http://img.blog.csdn.net/20141003113658894?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3FjcmU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=""> 还是在原来的 New CDT Project Wizard选项卡中，展开，Makefile项目，二进制解析器，勾选PE windows解析器，确定，如图所示。 <img src="http://img.blog.csdn.net/20141003113807484?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3FjcmU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=""> 好啦，配置工作完成，我们来测试一下新C语言项目。</p>
                  <h2 id="测试项目"><a href="#测试项目" class="headerlink" title="测试项目"></a>测试项目</h2>
                  <p>右键新建-&gt;项目-&gt;C项目 <img src="http://img.blog.csdn.net/20141003114106872?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3FjcmU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=""> 下一步，选择可执行文件，Hello World ANCI C Project 编译器选择 MinGw GCC 完成，如图所示： <img src="http://img.blog.csdn.net/20141003114126625?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3FjcmU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=""> 完成之后的界面应该是如下所示，点击构建项目，图中的红色圆圈，构建完成之后，右键运行程序 <img src="http://img.blog.csdn.net/20141003114748589?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3FjcmU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=""> <img src="http://img.blog.csdn.net/20141003114637750?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3FjcmU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=""> 运行结果： <img src="http://img.blog.csdn.net/20141003115048145?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3FjcmU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=""> 欢呼吧小伙伴们 ! Eclipse 配置C/C++环境到此完全结束，如果有问题欢迎交流。</p>
                  </p>
                </div>
              </div>
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-user"></i>
                  </span>
                  <span class="post-meta-item-text">作者</span>
                  <span><a href="/authors/崔庆才" class="author" itemprop="url" rel="index">崔庆才</a></span>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>
                  <time title="创建时间：2015-07-13 00:45:39" itemprop="dateCreated datePublished" datetime="2015-07-13T00:45:39+08:00">2015-07-13</time>
                </span>
                <span id="/1898.html" class="post-meta-item leancloud_visitors" data-flag-title="Winpcap网络编程二之环境配置，Eclipse配置C/C++环境" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="fa fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
                <span class="post-meta-item" title="本文字数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-file-word"></i>
                  </span>
                  <span class="post-meta-item-text">本文字数：</span>
                  <span>2.1k</span>
                </span>
                <span class="post-meta-item" title="阅读时长">
                  <span class="post-meta-item-icon">
                    <i class="far fa-clock"></i>
                  </span>
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                  <span>2 分钟</span>
                </span>
              </div>
            </article>
            <article itemscope itemtype="http://schema.org/Article" class="post-block index" lang="zh-CN">
              <link itemprop="mainEntityOfPage" href="https://cuiqingcai.com/1890.html">
              <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
                <meta itemprop="image" content="/images/avatar.png">
                <meta itemprop="name" content="崔庆才">
                <meta itemprop="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
              </span>
              <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
                <meta itemprop="name" content="静觅">
              </span>
              <header class="post-header">
                <h2 class="post-title" itemprop="name headline">
                  <a class="label"> C/C++ <i class="label-arrow"></i>
                  </a>
                  <a href="/1890.html" class="post-title-link" itemprop="url">Winpcap网络编程一之前言，实验要求，实验目标</a>
                </h2>
              </header>
              <div class="post-body" itemprop="articleBody">
                <div class="thumb">
                  <img itemprop="contentUrl" class="random">
                </div>
                <div class="excerpt">
                  <p>
                  <p>Hi，大家好，现在计算机网络课程设计开始啦，本次为大家带来计算机网络实验的系列讲解，希望对于小伙伴们的计网课设有一定帮助哦。</p>
                  <h2 id="写在前面"><a href="#写在前面" class="headerlink" title="写在前面"></a>写在前面</h2>
                  <p>首先，博主来自山东大学，这次计网课程设计的实验学校为山东大学，年级为2012级，请对号入座。 另外，对于上学期学的计算机网络课程知识，可以说我就是为了应付考试最后狂背下来的，感觉对于计算机网络里的一些原理真的没有理解。纯粹看一些概念性的东西真的是太抽象啦，这次计网课设的目的就是让我们用编程实现网络分析技术和网络功能仿真，来深入了解计算机网络知识。可以说这些才是学习计算机网络最重要的一环，大家加油。</p>
                  <h2 id="实验要求"><a href="#实验要求" class="headerlink" title="实验要求"></a>实验要求</h2>
                  <p>1、基本任务（达标任务） 完成两台主机之间的数据通信（数据链路层）</p>
                  <ul>
                    <li>仿真ARP协议获得网段内主机的MAC表</li>
                    <li>使用帧完成两台主机的通信（Hello! I’m …)</li>
                  </ul>
                  <p>2、高端任务（优秀任务） 完成两台主机通过中间主机的数据通信（网络层）</p>
                  <ul>
                    <li>增加基于IP地址的转发功能</li>
                    <li>增加网络层封装</li>
                  </ul>
                  <p>本次任务呢分为基本任务和高端任务，当然我们的目标当然不仅限于基本任务咯。</p>
                  <h2 id="实验概述"><a href="#实验概述" class="headerlink" title="实验概述"></a>实验概述</h2>
                  <p>一句话，我们需要利用winpcap这个库用C语言编程来实现以上的任务。</p>
                  <h2 id="winpcap讲解"><a href="#winpcap讲解" class="headerlink" title="winpcap讲解"></a>winpcap讲解</h2>
                  <p>那么winpcap是什么？ 大多数网络应用程序通过被广泛使用的操作系统原件来访问网络，如socket。由于操作系统已经处理了底层的细节问题（如协议的处理、数据包的封装等），并提供了与读写文件类似的函数接口，因此使用该方法可以很容易的访问网络中的数据 然而有些时候，这种简单的方式并不能满足任务要求，有些应用程序需要直接访问网络中的数据包，也就是说，需要访问哪些没有被操作系统处理过的数据包 WinPcap就是为Windows平台的应用程序提供这种访问方式，提供下列功能：</p>
                  <ul>
                    <li>捕获原始数据包。无论是发送到运行WinPcap的机器上的数据包，还是在其它主机（存在网络共享介质上的主机）上进行交换的数据包，都可以被捕获</li>
                    <li>在数据包传递给应用程序之前，根据用户指定的规则过滤数据包</li>
                    <li>将原始数据包发送到网络上</li>
                    <li>收集网络流量与网络状态的统计信息</li>
                  </ul>
                  <p>它提供给我们什么呢？</p>
                  <p>它包含一个内核空间数据包过滤器（Netgroup Packet Filter, NPF)，一个底层动态链接库（Packet.dll)和一个高层独立于操作系统的动态链接库(wpcap.dll)。各部分关系见下图</p>
                  <p><img src="http://img.blog.csdn.net/20141003103218640?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3FjcmU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=""> NPF：为了能够访问网络上传输的原始数据，数据包捕获系统需要绕过操作系统的协议栈。这就需要有一部分程序运行在操作系统的内核中，只有这样才能与网络接口驱动直接交互。在WinPcap中，与操作系统密切相关的是一个名为NPF的设备驱动程序，同时对不同版本的操作系统提供了不同版本的驱动程序。这些驱动程序提供了数据包捕获与发送的基本功能，同时提供了一个可编程的数据包过滤系统、一个网络监视引擎等高级功能。 动态链接库：为了让应用程序能够使用内核驱动提供的功能，数据包捕获系统必须导出相关的接口。对此，WinPcap提供两个不同层次的动态链接库：Packet.dll和wpcap.dll。 Packet.dll提供底层的API，用来直接访问驱动程序的函数，用来提供独立于微软公司不同操作系统的编程接口。 wpcap.dll库导出了更强大、更高层的捕获函数接口，具有与UNIX捕获库libpcap的兼容性。这两个库可使数据包的捕获独立于底层的网络硬件与操作系统。</p>
                  <h2 id="实验流程"><a href="#实验流程" class="headerlink" title="实验流程"></a>实验流程</h2>
                  <p>了解了winpcap之后，我们要做的就是利用它提供的类库来实现网络传输，网络解析等一系列的功能。</p>
                  <p>需要我们做好的准备有：</p>
                  <ul>
                    <li>C语言的相关基础</li>
                    <li>计算机网络的基础知识</li>
                    <li>对开发环境的相关了解</li>
                  </ul>
                  <p>如果对于上述中任何一个不熟悉，请先去补习一下基础知识吧。</p>
                  <h2 id="参考书目"><a href="#参考书目" class="headerlink" title="参考书目"></a>参考书目</h2>
                  <ul>
                    <li>吴功宜等，《计算机网络高级软件编程技术》（第2版），清华大学出版社</li>
                    <li>徐恪等， 《高级计算机网络》，清华大学出版社</li>
                    <li>A.S. Tannenbaum，《计算机网络》（第5版），清华大学出版社</li>
                    <li>吕雪峰等， 《网络分析技术揭秘（原理、实践与WinPcap深入解析》，机械工业出版社</li>
                  </ul>
                  <h2 id="结语"><a href="#结语" class="headerlink" title="结语"></a>结语</h2>
                  <p>下一节，我们将讲解在Eclipse环境下搭建winpcap环境的具体步骤。本次讲解到此结束，谢谢大家。</p>
                  </p>
                </div>
              </div>
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-user"></i>
                  </span>
                  <span class="post-meta-item-text">作者</span>
                  <span><a href="/authors/崔庆才" class="author" itemprop="url" rel="index">崔庆才</a></span>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>
                  <time title="创建时间：2015-07-13 00:35:59" itemprop="dateCreated datePublished" datetime="2015-07-13T00:35:59+08:00">2015-07-13</time>
                </span>
                <span id="/1890.html" class="post-meta-item leancloud_visitors" data-flag-title="Winpcap网络编程一之前言，实验要求，实验目标" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="fa fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
                <span class="post-meta-item" title="本文字数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-file-word"></i>
                  </span>
                  <span class="post-meta-item-text">本文字数：</span>
                  <span>1.7k</span>
                </span>
                <span class="post-meta-item" title="阅读时长">
                  <span class="post-meta-item-icon">
                    <i class="far fa-clock"></i>
                  </span>
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                  <span>2 分钟</span>
                </span>
              </div>
            </article>
            <article itemscope itemtype="http://schema.org/Article" class="post-block index" lang="zh-CN">
              <link itemprop="mainEntityOfPage" href="https://cuiqingcai.com/1883.html">
              <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
                <meta itemprop="image" content="/images/avatar.png">
                <meta itemprop="name" content="崔庆才">
                <meta itemprop="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
              </span>
              <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
                <meta itemprop="name" content="静觅">
              </span>
              <header class="post-header">
                <h2 class="post-title" itemprop="name headline">
                  <a class="label"> 个人日记 <i class="label-arrow"></i>
                  </a>
                  <a href="/1883.html" class="post-title-link" itemprop="url">假期到啦，重新回归代码之路</a>
                </h2>
              </header>
              <div class="post-body" itemprop="articleBody">
                <div class="thumb">
                  <img itemprop="contentUrl" class="random">
                </div>
                <div class="excerpt">
                  <p>
                  <p>二零一五年七月九日，伴随着最后一门图形学交卷铃声的想起，我的大三正式结束了。首先很抱歉，最近一段时间一直在忙考试复习，时间也比较紧张，另外就是整理各种材料，还有准备一些面试，也算是忙得不亦乐乎，所以，这段时间也没有去编代码，大约也有一个月的时间没有更新博客了，有好多热心的朋友在我博客留言评论，也没有及时回复，在这里向大家说一声抱歉。放假回家之后，我会好好研究一下大家提出的意见和建议，给予大家回复的。 恩，接下来的日子应该会稍微轻松那么一点，自己的研究生路大体有了轮廓，有了规划。将来想从事的方向为信息安全方向，自己也做过一些项目和网站，对一些安全性问题要求也是比较高的，自己也对安全问题比较感兴趣，嗯。 现在时间是二零一五年七月十二日，昨天回家，收拾整顿一番，今天假期正式开始啦！ 上学期是我大学的第六个学期了，对于保研来说，也着实是最后的一个重要的学期了，学习上也要更加重视。仔细回想起来，这个学期实际的项目开发没有做过多少，和同学开发了一个演唱会支付系统，又完善了一下自己之前的项目。学期后期，基本上就是准备一些面试和靠前复习，另外还有一些研究生招生的面试咨询等等，结果就不透露啦，自我感觉还是不错。 本来有好多话想说，然而这个时间，却不想多言了。 心里的石头还没落地，最近的日子，好好准备即将到来的面试。暑假到了，想要学习的东西还有很多，重新开启我的代码之路！Come On！</p>
                  <p>崔庆才</p>
                  <p>2015/7/12</p>
                  </p>
                </div>
              </div>
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-user"></i>
                  </span>
                  <span class="post-meta-item-text">作者</span>
                  <span><a href="/authors/崔庆才" class="author" itemprop="url" rel="index">崔庆才</a></span>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>
                  <time title="创建时间：2015-07-12 11:08:25" itemprop="dateCreated datePublished" datetime="2015-07-12T11:08:25+08:00">2015-07-12</time>
                </span>
                <span id="/1883.html" class="post-meta-item leancloud_visitors" data-flag-title="假期到啦，重新回归代码之路" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="fa fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
                <span class="post-meta-item" title="本文字数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-file-word"></i>
                  </span>
                  <span class="post-meta-item-text">本文字数：</span>
                  <span>599</span>
                </span>
                <span class="post-meta-item" title="阅读时长">
                  <span class="post-meta-item-icon">
                    <i class="far fa-clock"></i>
                  </span>
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                  <span>1 分钟</span>
                </span>
              </div>
            </article>
            <article itemscope itemtype="http://schema.org/Article" class="post-block index" lang="zh-CN">
              <link itemprop="mainEntityOfPage" href="https://cuiqingcai.com/1867.html">
              <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
                <meta itemprop="image" content="/images/avatar.png">
                <meta itemprop="name" content="崔庆才">
                <meta itemprop="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
              </span>
              <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
                <meta itemprop="name" content="静觅">
              </span>
              <header class="post-header">
                <h2 class="post-title" itemprop="name headline">
                  <a class="label"> C/C++ <i class="label-arrow"></i>
                  </a>
                  <a href="/1867.html" class="post-title-link" itemprop="url">OpenGL绘图实例十之绘制3D机器人</a>
                </h2>
              </header>
              <div class="post-body" itemprop="articleBody">
                <div class="thumb">
                  <img itemprop="contentUrl" class="random">
                </div>
                <div class="excerpt">
                  <p>
                  <h2 id="综述"><a href="#综述" class="headerlink" title="综述"></a>综述</h2>
                  <p>通过上一节说的绘制3D图形基础，我们应该对绘制3D图形有了基本的认识，接下来我们就进行一个实例，绘制一个3D机器人。 本节我们要完成的任务有：</p>
                  <blockquote>
                    <p>1.绘制一个仿真3D机器人(样式自选，参考例图)，至少包含头、躯干、四肢三个部分. 2.对机器人填充颜色。 3.增加点光源，使得机器人更加真实。 4.实现交互，使得能够控制机器人进行旋转、前进、后退等动作。 键盘”w”:前进 键盘”s”:后退 键盘”a”:顺时针旋转 键盘”d”:逆时针旋转</p>
                  </blockquote>
                  <p>接下来我们就一步步实现机器人的绘制吧。</p>
                  <h2 id="绘制球体"><a href="#绘制球体" class="headerlink" title="绘制球体"></a>绘制球体</h2>
                  <p>绘制球体我们有两种方法，一个叫glutSolidSphere，另一个叫glutWireSphere，这两个的区别在于，一个绘制的是实心的球体，另一个绘制的是现状描绘而成的球体，在绘制过程中，我们可以通过一个参数来对其进行控制。 glutSolidSphere是GLUT工具包中的一个函数，该函数用于渲染一个球体。球体球心位于原点。在OpenGL中默认的原点就是窗口客户区的中心。 函数原型</p>
                  <figure class="highlight routeros">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">void glutSolidSphere(GLdouble<span class="built_in"> radius </span>, GLint slices , GLint stacks);</span><br><span class="line">void glutWireSphere(GLdouble radius, GLint slices, GLint stacks );</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>radius，球体的半径 slices，以Z轴上线段为直径分布的圆周线的条数（将Z轴看成地球的地轴，类似于经线） stacks，围绕在Z轴周围的线的条数（类似于地球上纬线） 一般而言， 后两个参数赋予较大的值， 渲染花费的时间要长， 效果更逼真。 然而我们可以发现，这里并没有定义球中心的参数，所以，我们可以利用平移函数组合实现。即利用glTranslated函数来实现。最后，我们定义的画球体的方法如下</p>
                  <figure class="highlight reasonml">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="comment">//画球</span></span><br><span class="line">void draw<span class="constructor">Ball(<span class="params">double</span> R, <span class="params">double</span> <span class="params">x</span>, <span class="params">double</span> <span class="params">y</span>,<span class="params">double</span> <span class="params">z</span>, <span class="params">int</span> MODE)</span> &#123;</span><br><span class="line">	gl<span class="constructor">PushMatrix()</span>;</span><br><span class="line">	gl<span class="constructor">Translated(<span class="params">x</span>,<span class="params">y</span>,<span class="params">z</span>)</span>;</span><br><span class="line">	<span class="keyword">if</span> (MODE<span class="operator"> == </span>SOLID) &#123;</span><br><span class="line">		glut<span class="constructor">SolidSphere(R,20,20)</span>;</span><br><span class="line">	&#125; <span class="keyword">else</span> <span class="keyword">if</span> (MODE ==WIRE) &#123;</span><br><span class="line">		glut<span class="constructor">WireSphere(R,20,20)</span>;</span><br><span class="line">	&#125;</span><br><span class="line">	gl<span class="constructor">PopMatrix()</span>;</span><br><span class="line">&#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>其中两个常量定义如下</p>
                  <figure class="highlight cpp">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="meta">#<span class="meta-keyword">define</span> SOLID 1</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> WIRE 2</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>在这里我们还用到了上一节所说的PushMatrix和PopMatrix方法。如果不熟悉，请查看上一节的内容。</p>
                  <h2 id="绘制长方体"><a href="#绘制长方体" class="headerlink" title="绘制长方体"></a>绘制长方体</h2>
                  <p>同样地，利用变换平移放缩的方法，再加上类库的绘制正方体的方法，我们也可以轻松地实现绘制长方体的方法。 正方体怎样变成长方体，很简单，拉伸一下就好了。所以，我们用到了glScaled方法。 绘制长方体的方法如下</p>
                  <figure class="highlight reasonml">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="comment">//画长方体</span></span><br><span class="line">void draw<span class="constructor">Skewed(<span class="params">double</span> <span class="params">l</span>, <span class="params">double</span> <span class="params">w</span>, <span class="params">double</span> <span class="params">h</span>, <span class="params">double</span> <span class="params">x</span>, <span class="params">double</span> <span class="params">y</span>, <span class="params">double</span> <span class="params">z</span>, <span class="params">int</span> MODE)</span> &#123;</span><br><span class="line">	gl<span class="constructor">PushMatrix()</span>;</span><br><span class="line">	gl<span class="constructor">Scaled(<span class="params">l</span>, <span class="params">w</span>, <span class="params">h</span>)</span>;</span><br><span class="line">	gl<span class="constructor">Translated(<span class="params">x</span>, <span class="params">y</span>, <span class="params">z</span>)</span>;</span><br><span class="line">	<span class="keyword">if</span> (MODE<span class="operator"> == </span>SOLID) &#123;</span><br><span class="line">		glut<span class="constructor">SolidCube(1)</span>;</span><br><span class="line">	&#125; <span class="keyword">else</span> <span class="keyword">if</span> (MODE<span class="operator"> == </span>WIRE) &#123;</span><br><span class="line">		glut<span class="constructor">WireCube(1)</span>;</span><br><span class="line">	&#125;</span><br><span class="line">	gl<span class="constructor">PopMatrix()</span>;</span><br><span class="line">&#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>这里仍然还是定义了绘图模式，是线条还是实体。</p>
                  <h2 id="定义光照"><a href="#定义光照" class="headerlink" title="定义光照"></a>定义光照</h2>
                  <p>在这里提供一篇博文，讲光照讲得比较细致 <a href="http://www.cnblogs.com/opengl/archive/2012/11/14/2770745.html" target="_blank" rel="noopener">OPENGL光照</a> 那么在这里我就直接贴上光照设置的实现</p>
                  <figure class="highlight angelscript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="built_in">void</span> init() &#123;</span><br><span class="line">   <span class="comment">//定义光源的颜色和位置</span></span><br><span class="line">   GLfloat ambient[] = &#123; <span class="number">0.5</span>, <span class="number">0.8</span>, <span class="number">0.1</span>, <span class="number">0.1</span> &#125;;  </span><br><span class="line">   GLfloat diffuse[] = &#123; <span class="number">1.0</span>, <span class="number">1.0</span>, <span class="number">1.0</span>, <span class="number">1.0</span> &#125;;  </span><br><span class="line">   GLfloat position[] = &#123; <span class="number">-80.0</span>, <span class="number">50.0</span>, <span class="number">25.0</span>, <span class="number">1.0</span> &#125;;  </span><br><span class="line">   <span class="comment">//选择光照模型</span></span><br><span class="line">   GLfloat lmodel_ambient[] = &#123; <span class="number">0.4</span>, <span class="number">0.4</span>, <span class="number">0.4</span>, <span class="number">1.0</span> &#125;;  </span><br><span class="line">   GLfloat local_view[] = &#123; <span class="number">0.0</span> &#125;;  </span><br><span class="line">   glClearColor(<span class="number">0.0</span>, <span class="number">0.0</span>, <span class="number">0.0</span>, <span class="number">0.0</span>);   </span><br><span class="line">   glShadeModel(GL_SMOOTH);  </span><br><span class="line">   <span class="comment">//设置环境光</span></span><br><span class="line">   glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);  </span><br><span class="line">   <span class="comment">//设置漫射光</span></span><br><span class="line">   glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);  </span><br><span class="line">   <span class="comment">//设置光源位置</span></span><br><span class="line">   glLightfv(GL_LIGHT0, GL_POSITION, position);  </span><br><span class="line">   glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);  </span><br><span class="line">   glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, local_view);  </span><br><span class="line">   <span class="comment">//启动光照</span></span><br><span class="line">   glEnable(GL_LIGHTING);  </span><br><span class="line">   <span class="comment">//启用光源</span></span><br><span class="line">   glEnable(GL_LIGHT0);  </span><br><span class="line">&#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>其中设置了光源颜色，位置等参数。</p>
                  <h2 id="图形的移动"><a href="#图形的移动" class="headerlink" title="图形的移动"></a>图形的移动</h2>
                  <p>在这里我们实现了鼠标的监听旋转和键盘的监听旋转，在这里分别描述如下</p>
                  <h3 id="1-鼠标监听"><a href="#1-鼠标监听" class="headerlink" title="1.鼠标监听"></a>1.鼠标监听</h3>
                  <p>对于鼠标监听事件，在前面的文章中已经做了说明，如果大家不熟悉可以看下面这篇文章 <a href="http://cuiqingcai.com/1776.html">鼠标监听</a> 我们要实现的就是在拖动鼠标的时候实现图形的旋转功能。 在点击鼠标时，我们记录下来点击的位置，然后在鼠标移动的时候记录下当前坐标与上一个位置的坐标之差。通过定义一个角度的变量，每次鼠标移动的时候让整个图形旋转角度加上这个差值，然后重新绘制图形，就可以实现整个图形的 旋转了。 鼠标监听的两个方法如下，分别是鼠标点击和鼠标移动。 定义两个变量，旋转角度</p>
                  <figure class="highlight angelscript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="built_in">int</span> spinX = <span class="number">0</span>;</span><br><span class="line"><span class="built_in">int</span> spinY = <span class="number">0</span>;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>然后定义两个鼠标事件</p>
                  <figure class="highlight cpp">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="comment">// 鼠标移动事件 </span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">mouseMove</span><span class="params">(<span class="keyword">int</span> x, <span class="keyword">int</span> y)</span> </span>&#123;</span><br><span class="line">	<span class="keyword">int</span> dx = x - moveX;</span><br><span class="line">	<span class="keyword">int</span> dy = y - moveY;</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">"dx;%dx,dy:%dy\n"</span>,dx,dy);</span><br><span class="line">	spinX += dx;</span><br><span class="line">	spinY += dy;</span><br><span class="line">	glutPostRedisplay();</span><br><span class="line">	moveX = x;</span><br><span class="line">	moveY = y;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//鼠标点击事件</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">mouseClick</span><span class="params">(<span class="keyword">int</span> btn, <span class="keyword">int</span> state, <span class="keyword">int</span> x, <span class="keyword">int</span> y)</span> </span>&#123;</span><br><span class="line">    moveX = x;</span><br><span class="line">	moveY = y; </span><br><span class="line">&#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>恩，通过定义上面的方法，然后在main中加入监听。</p>
                  <figure class="highlight reasonml">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="comment">//鼠标点击事件，鼠标点击或者松开时调用</span></span><br><span class="line">    glut<span class="constructor">MouseFunc(<span class="params">mouseClick</span>)</span>;</span><br><span class="line">	<span class="comment">//鼠标移动事件，鼠标按下并移动时调用</span></span><br><span class="line">    glut<span class="constructor">MotionFunc(<span class="params">mouseMove</span>)</span>;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>display函数中，在绘图前调用该方法即可</p>
                  <figure class="highlight angelscript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">glRotated(spinX, <span class="number">0</span>, <span class="number">1</span>, <span class="number">0</span>);</span><br><span class="line">	glRotated(spinY, <span class="number">1</span>, <span class="number">0</span>, <span class="number">0</span>);</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>分别是绕y轴和x轴旋转一定的角度。这样就可以实现鼠标的监听了。</p>
                  <h3 id="2-键盘监听"><a href="#2-键盘监听" class="headerlink" title="2.键盘监听"></a>2.键盘监听</h3>
                  <p>键盘事件也很简单，同样是监听按键的按下。其中w、s键是用来控制机器人的远近的。 定义一个变量叫 dis，代表远近 键盘事件函数如下：</p>
                  <figure class="highlight processing">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="comment">//键盘事件</span></span><br><span class="line"><span class="keyword">void</span> <span class="built_in">keyPressed</span>(unsigned <span class="built_in">char</span> <span class="built_in">key</span>, <span class="built_in">int</span> x, <span class="built_in">int</span> y) &#123;</span><br><span class="line">    <span class="keyword">switch</span> (<span class="built_in">key</span>) &#123;</span><br><span class="line">    <span class="keyword">case</span> <span class="string">'a'</span>:</span><br><span class="line">        spinX -= <span class="number">2</span>;</span><br><span class="line">        <span class="keyword">break</span>;</span><br><span class="line">    <span class="keyword">case</span> <span class="string">'d'</span>:</span><br><span class="line">         spinX += <span class="number">2</span>;  </span><br><span class="line">        <span class="keyword">break</span>;</span><br><span class="line">    <span class="keyword">case</span> <span class="string">'w'</span>:</span><br><span class="line">        des += <span class="number">2</span>;</span><br><span class="line">        <span class="keyword">break</span>;</span><br><span class="line">    <span class="keyword">case</span> <span class="string">'s'</span>:</span><br><span class="line">        des -= <span class="number">2</span>;</span><br><span class="line">		<span class="keyword">break</span>;</span><br><span class="line">	&#125;</span><br><span class="line">	glutPostRedisplay();</span><br><span class="line">&#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>在main函数中加入监听</p>
                  <figure class="highlight reasonml">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="comment">//键盘事件</span></span><br><span class="line">	glut<span class="constructor">KeyboardFunc(<span class="params">keyPressed</span>)</span>;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>display函数中加入如下的变换</p>
                  <figure class="highlight angelscript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">glRotated(spinX, <span class="number">0</span>, <span class="number">1</span>, <span class="number">0</span>);</span><br><span class="line">	glRotated(spinY, <span class="number">1</span>, <span class="number">0</span>, <span class="number">0</span>);</span><br><span class="line">	glTranslated(<span class="number">0</span>, <span class="number">0</span>, des);</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>这样通过上述方法，我们便可以实现鼠标和键盘的监听了。</p>
                  <h2 id="裁切物体"><a href="#裁切物体" class="headerlink" title="裁切物体"></a>裁切物体</h2>
                  <p>在这里我们可能要画一个半圆，那么最方便的方法就是裁切了，利用下面的函数，我们可以方便地实现。</p>
                  <h3 id="void-glClipPlane-GLenum-plane-const-GLdouble-equation"><a href="#void-glClipPlane-GLenum-plane-const-GLdouble-equation" class="headerlink" title="void glClipPlane(GLenum plane, const GLdouble *equation);"></a>void glClipPlane(GLenum plane, const GLdouble *equation);</h3>
                  <p>定义一个裁剪平面。equation参数指向平面方程Ax + By + Cz + D = 0的4个系数。 equation=（0，-1，0,0），前三个参数（0，-1,0）可以理解为法线向下，只有向下的，即Y&lt;0的才能显示，最后一个参数0表示从z=0平面开始。这样就是裁剪掉上半平面。 equation=（0,1,0,0）表示裁剪掉下半平面， equation=（1,0,0,0）表示裁剪掉左半平面， equation=（-1,0,0,0）表示裁剪掉右半平面， equation=（0,0,-1,0）表示裁剪掉前半平面， equation=（0,0,1,0）表示裁剪掉后半平面 代码示例如下</p>
                  <figure class="highlight reasonml">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">GLdouble eqn<span class="literal">[<span class="number">4</span>]</span>=&#123;<span class="number">0.0</span>,<span class="number">0.0</span>,-<span class="number">1.0</span>,<span class="number">0.0</span>&#125;;</span><br><span class="line">gl<span class="constructor">ClipPlane(GL_CLIP_PLANE0,<span class="params">eqn</span>)</span>;</span><br><span class="line">gl<span class="constructor">Enable(GL_CLIP_PLANE0)</span>;</span><br><span class="line">glut<span class="constructor">SolidSphere(<span class="params">headR</span>,<span class="params">slices</span>,<span class="params">slices</span>)</span>;</span><br><span class="line">gl<span class="constructor">Disable(GL_CLIP_PLANE0)</span>;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>首先我们必须要定义一个GLdouble数组，然后利用glClipPlane方法来设置，然后开启裁切，最后关闭裁切。 利用类似的方法我们可以写出绘制半球的方法如下</p>
                  <figure class="highlight reasonml">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="comment">//画半球</span></span><br><span class="line">void draw<span class="constructor">HalfBall(<span class="params">double</span> R, <span class="params">double</span> <span class="params">x</span>, <span class="params">double</span> <span class="params">y</span>,<span class="params">double</span> <span class="params">z</span>, <span class="params">int</span> MODE)</span> &#123;</span><br><span class="line">	gl<span class="constructor">PushMatrix()</span>;</span><br><span class="line">	gl<span class="constructor">Translated(<span class="params">x</span>,<span class="params">y</span>,<span class="params">z</span>)</span>;</span><br><span class="line">	GLdouble eqn<span class="literal">[<span class="number">4</span>]</span>=&#123;<span class="number">0.0</span>, <span class="number">1.0</span>, <span class="number">0.0</span>, <span class="number">0.0</span>&#125;;</span><br><span class="line">	gl<span class="constructor">ClipPlane(GL_CLIP_PLANE0,<span class="params">eqn</span>)</span>;</span><br><span class="line">	gl<span class="constructor">Enable(GL_CLIP_PLANE0)</span>;</span><br><span class="line">	<span class="keyword">if</span> (MODE<span class="operator"> == </span>SOLID) &#123;</span><br><span class="line">		glut<span class="constructor">SolidSphere(R,20,20)</span>;</span><br><span class="line">	&#125; <span class="keyword">else</span> <span class="keyword">if</span> (MODE ==WIRE) &#123;</span><br><span class="line">		glut<span class="constructor">WireSphere(R,20,20)</span>;</span><br><span class="line">	&#125;</span><br><span class="line">	gl<span class="constructor">Disable(GL_CLIP_PLANE0)</span>;</span><br><span class="line">	gl<span class="constructor">PopMatrix()</span>;</span><br><span class="line">&#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>恩，通过上述方法，我们可以方便地绘制出一个半球体。</p>
                  <h2 id="绘制机器人"><a href="#绘制机器人" class="headerlink" title="绘制机器人"></a>绘制机器人</h2>
                  <p>有了上述的铺垫，我们绘制机器人简直易如反掌，同样还可以实现各式各样的监听。 主要就是位置的确定了。 display函数如下</p>
                  <figure class="highlight angelscript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="built_in">void</span> display(<span class="built_in">void</span>) &#123;</span><br><span class="line">	<span class="comment">//清除缓冲区颜色</span></span><br><span class="line">	glClear(GL_COLOR_BUFFER_BIT);</span><br><span class="line">	<span class="comment">//定义白色</span></span><br><span class="line">	glColor3f(<span class="number">1.0</span>, <span class="number">1.0</span>, <span class="number">1.0</span>); </span><br><span class="line">	<span class="comment">//圆点放坐标中心</span></span><br><span class="line">	glLoadIdentity();  </span><br><span class="line">	<span class="comment">//从哪个地方看</span></span><br><span class="line">	gluLookAt(<span class="number">-2.0</span>, <span class="number">-1.0</span>, <span class="number">20.0</span>, <span class="number">0.0</span>, <span class="number">0.0</span>, <span class="number">0.0</span>, <span class="number">0.0</span>, <span class="number">1.0</span>, <span class="number">0.0</span>); </span><br><span class="line">	glPushMatrix();</span><br><span class="line">	glRotated(spinX, <span class="number">0</span>, <span class="number">1</span>, <span class="number">0</span>);</span><br><span class="line">	glRotated(spinY, <span class="number">1</span>, <span class="number">0</span>, <span class="number">0</span>);</span><br><span class="line">	glTranslated(<span class="number">0</span>, <span class="number">0</span>, des);</span><br><span class="line">	<span class="comment">//头</span></span><br><span class="line">	drawBall(<span class="number">2</span>, <span class="number">0</span>, <span class="number">1</span>, <span class="number">0</span>, SOLID);</span><br><span class="line">	<span class="comment">//身体</span></span><br><span class="line">	drawSkewed(<span class="number">5</span>, <span class="number">4.4</span>, <span class="number">4</span>, <span class="number">0</span>, <span class="number">-0.75</span>, <span class="number">0</span>, SOLID);</span><br><span class="line">	<span class="comment">//肩膀</span></span><br><span class="line">	drawHalfBall(<span class="number">1</span>, <span class="number">3.5</span>, <span class="number">-2.1</span>, <span class="number">0</span>, SOLID);</span><br><span class="line">	drawHalfBall(<span class="number">1</span>, <span class="number">-3.5</span>, <span class="number">-2.1</span>, <span class="number">0</span>, SOLID);</span><br><span class="line">	<span class="comment">//胳膊</span></span><br><span class="line">	drawSkewed(<span class="number">1</span>, <span class="number">3</span>, <span class="number">1</span>, <span class="number">3.5</span>, <span class="number">-1.3</span>, <span class="number">0</span>, SOLID);</span><br><span class="line">	drawSkewed(<span class="number">1</span>, <span class="number">3</span>, <span class="number">1</span>, <span class="number">-3.5</span>, <span class="number">-1.3</span>, <span class="number">0</span>, SOLID);</span><br><span class="line">	<span class="comment">//手</span></span><br><span class="line">	drawBall(<span class="number">1</span>, <span class="number">3.5</span>, <span class="number">-6.4</span>, <span class="number">0</span>, SOLID);</span><br><span class="line">	drawBall(<span class="number">1</span>, <span class="number">-3.5</span>, <span class="number">-6.4</span>, <span class="number">0</span>, SOLID);</span><br><span class="line">	<span class="comment">//腿</span></span><br><span class="line">	drawSkewed(<span class="number">1.2</span>, <span class="number">3</span>, <span class="number">2</span>, <span class="number">1</span>, <span class="number">-2.4</span>, <span class="number">0</span>, SOLID);</span><br><span class="line">	drawSkewed(<span class="number">1.2</span>, <span class="number">3</span>, <span class="number">2</span>, <span class="number">-1</span>, <span class="number">-2.4</span>, <span class="number">0</span>, SOLID);</span><br><span class="line">	<span class="comment">//脚</span></span><br><span class="line">	drawSkewed(<span class="number">1.5</span>, <span class="number">1</span>, <span class="number">3</span>, <span class="number">0.9</span>, <span class="number">-9.2</span>, <span class="number">0</span>, SOLID);</span><br><span class="line">	drawSkewed(<span class="number">1.5</span>, <span class="number">1</span>, <span class="number">3</span>, <span class="number">-0.9</span>, <span class="number">-9.2</span>, <span class="number">0</span>, SOLID);</span><br><span class="line">	glPopMatrix();</span><br><span class="line">    glutSwapBuffers();</span><br><span class="line">&#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>恩，通过调用这个函数我们便可以完成机器人的绘制了。</p>
                  <h2 id="完整代码"><a href="#完整代码" class="headerlink" title="完整代码"></a>完整代码</h2>
                  <p>在这里提供完整代码示例，仅供参考</p>
                  <figure class="highlight angelscript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">#include &lt;glut.h&gt;</span><br><span class="line">#include &lt;stdlib.h&gt;</span><br><span class="line">#include &lt;stdio.h&gt;</span><br><span class="line"></span><br><span class="line">#define SOLID <span class="number">1</span></span><br><span class="line">#define WIRE <span class="number">2</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">int</span> moveX,moveY;</span><br><span class="line"><span class="built_in">int</span> spinX = <span class="number">0</span>;</span><br><span class="line"><span class="built_in">int</span> spinY = <span class="number">0</span>;</span><br><span class="line"><span class="built_in">int</span> des = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="built_in">void</span> init() &#123;</span><br><span class="line">   <span class="comment">//定义光源的颜色和位置</span></span><br><span class="line">   GLfloat ambient[] = &#123; <span class="number">0.5</span>, <span class="number">0.8</span>, <span class="number">0.1</span>, <span class="number">0.1</span> &#125;;  </span><br><span class="line">   GLfloat diffuse[] = &#123; <span class="number">1.0</span>, <span class="number">1.0</span>, <span class="number">1.0</span>, <span class="number">1.0</span> &#125;;  </span><br><span class="line">   GLfloat position[] = &#123; <span class="number">-80.0</span>, <span class="number">50.0</span>, <span class="number">25.0</span>, <span class="number">1.0</span> &#125;;  </span><br><span class="line">   <span class="comment">//选择光照模型</span></span><br><span class="line">   GLfloat lmodel_ambient[] = &#123; <span class="number">0.4</span>, <span class="number">0.4</span>, <span class="number">0.4</span>, <span class="number">1.0</span> &#125;;  </span><br><span class="line">   GLfloat local_view[] = &#123; <span class="number">0.0</span> &#125;;  </span><br><span class="line">   glClearColor(<span class="number">0.0</span>, <span class="number">0.0</span>, <span class="number">0.0</span>, <span class="number">0.0</span>);   </span><br><span class="line">   glShadeModel(GL_SMOOTH);  </span><br><span class="line">   <span class="comment">//设置环境光</span></span><br><span class="line">   glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);  </span><br><span class="line">   <span class="comment">//设置漫射光</span></span><br><span class="line">   glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);  </span><br><span class="line">   <span class="comment">//设置光源位置</span></span><br><span class="line">   glLightfv(GL_LIGHT0, GL_POSITION, position);  </span><br><span class="line">   glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);  </span><br><span class="line">   glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, local_view);  </span><br><span class="line">   <span class="comment">//启动光照</span></span><br><span class="line">   glEnable(GL_LIGHTING);  </span><br><span class="line">   <span class="comment">//启用光源</span></span><br><span class="line">   glEnable(GL_LIGHT0);  </span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//画球</span></span><br><span class="line"><span class="built_in">void</span> drawBall(<span class="built_in">double</span> R, <span class="built_in">double</span> x, <span class="built_in">double</span> y,<span class="built_in">double</span> z, <span class="built_in">int</span> MODE) &#123;</span><br><span class="line">	glPushMatrix();</span><br><span class="line">	glTranslated(x,y,z);</span><br><span class="line">	<span class="keyword">if</span> (MODE == SOLID) &#123;</span><br><span class="line">		glutSolidSphere(R,<span class="number">20</span>,<span class="number">20</span>);</span><br><span class="line">	&#125; <span class="keyword">else</span> <span class="keyword">if</span> (MODE ==WIRE) &#123;</span><br><span class="line">		glutWireSphere(R,<span class="number">20</span>,<span class="number">20</span>);</span><br><span class="line">	&#125;</span><br><span class="line">	glPopMatrix();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//画半球</span></span><br><span class="line"><span class="built_in">void</span> drawHalfBall(<span class="built_in">double</span> R, <span class="built_in">double</span> x, <span class="built_in">double</span> y,<span class="built_in">double</span> z, <span class="built_in">int</span> MODE) &#123;</span><br><span class="line">	glPushMatrix();</span><br><span class="line">	glTranslated(x,y,z);</span><br><span class="line">	GLdouble eqn[<span class="number">4</span>]=&#123;<span class="number">0.0</span>, <span class="number">1.0</span>, <span class="number">0.0</span>, <span class="number">0.0</span>&#125;;</span><br><span class="line">	glClipPlane(GL_CLIP_PLANE0,eqn);</span><br><span class="line">	glEnable(GL_CLIP_PLANE0);</span><br><span class="line">	<span class="keyword">if</span> (MODE == SOLID) &#123;</span><br><span class="line">		glutSolidSphere(R,<span class="number">20</span>,<span class="number">20</span>);</span><br><span class="line">	&#125; <span class="keyword">else</span> <span class="keyword">if</span> (MODE ==WIRE) &#123;</span><br><span class="line">		glutWireSphere(R,<span class="number">20</span>,<span class="number">20</span>);</span><br><span class="line">	&#125;</span><br><span class="line">	glDisable(GL_CLIP_PLANE0);</span><br><span class="line">	glPopMatrix();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//画长方体</span></span><br><span class="line"><span class="built_in">void</span> drawSkewed(<span class="built_in">double</span> l, <span class="built_in">double</span> w, <span class="built_in">double</span> h, <span class="built_in">double</span> x, <span class="built_in">double</span> y, <span class="built_in">double</span> z, <span class="built_in">int</span> MODE) &#123;</span><br><span class="line">	glPushMatrix();</span><br><span class="line">	glScaled(l, w, h);</span><br><span class="line">	glTranslated(x, y, z);</span><br><span class="line">	<span class="keyword">if</span> (MODE == SOLID) &#123;</span><br><span class="line">		glutSolidCube(<span class="number">1</span>);</span><br><span class="line">	&#125; <span class="keyword">else</span> <span class="keyword">if</span> (MODE ==WIRE) &#123;</span><br><span class="line">		glutWireCube(<span class="number">1</span>);</span><br><span class="line">	&#125;</span><br><span class="line">	glPopMatrix();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="built_in">void</span> display(<span class="built_in">void</span>) &#123;</span><br><span class="line">	<span class="comment">//清除缓冲区颜色</span></span><br><span class="line">	glClear(GL_COLOR_BUFFER_BIT);</span><br><span class="line">	<span class="comment">//定义白色</span></span><br><span class="line">	glColor3f(<span class="number">1.0</span>, <span class="number">1.0</span>, <span class="number">1.0</span>); </span><br><span class="line">	<span class="comment">//圆点放坐标中心</span></span><br><span class="line">	glLoadIdentity();  </span><br><span class="line">	<span class="comment">//从哪个地方看</span></span><br><span class="line">	gluLookAt(<span class="number">-2.0</span>, <span class="number">-1.0</span>, <span class="number">20.0</span>, <span class="number">0.0</span>, <span class="number">0.0</span>, <span class="number">0.0</span>, <span class="number">0.0</span>, <span class="number">1.0</span>, <span class="number">0.0</span>); </span><br><span class="line">	glPushMatrix();</span><br><span class="line">	glRotated(spinX, <span class="number">0</span>, <span class="number">1</span>, <span class="number">0</span>);</span><br><span class="line">	glRotated(spinY, <span class="number">1</span>, <span class="number">0</span>, <span class="number">0</span>);</span><br><span class="line">	glTranslated(<span class="number">0</span>, <span class="number">0</span>, des);</span><br><span class="line">	<span class="comment">//头</span></span><br><span class="line">	drawBall(<span class="number">2</span>, <span class="number">0</span>, <span class="number">1</span>, <span class="number">0</span>, SOLID);</span><br><span class="line">	<span class="comment">//身体</span></span><br><span class="line">	drawSkewed(<span class="number">5</span>, <span class="number">4.4</span>, <span class="number">4</span>, <span class="number">0</span>, <span class="number">-0.75</span>, <span class="number">0</span>, SOLID);</span><br><span class="line">	<span class="comment">//肩膀</span></span><br><span class="line">	drawHalfBall(<span class="number">1</span>, <span class="number">3.5</span>, <span class="number">-2.1</span>, <span class="number">0</span>, SOLID);</span><br><span class="line">	drawHalfBall(<span class="number">1</span>, <span class="number">-3.5</span>, <span class="number">-2.1</span>, <span class="number">0</span>, SOLID);</span><br><span class="line">	<span class="comment">//胳膊</span></span><br><span class="line">	drawSkewed(<span class="number">1</span>, <span class="number">3</span>, <span class="number">1</span>, <span class="number">3.5</span>, <span class="number">-1.3</span>, <span class="number">0</span>, SOLID);</span><br><span class="line">	drawSkewed(<span class="number">1</span>, <span class="number">3</span>, <span class="number">1</span>, <span class="number">-3.5</span>, <span class="number">-1.3</span>, <span class="number">0</span>, SOLID);</span><br><span class="line">	<span class="comment">//手</span></span><br><span class="line">	drawBall(<span class="number">1</span>, <span class="number">3.5</span>, <span class="number">-6.4</span>, <span class="number">0</span>, SOLID);</span><br><span class="line">	drawBall(<span class="number">1</span>, <span class="number">-3.5</span>, <span class="number">-6.4</span>, <span class="number">0</span>, SOLID);</span><br><span class="line">	<span class="comment">//腿</span></span><br><span class="line">	drawSkewed(<span class="number">1.2</span>, <span class="number">3</span>, <span class="number">2</span>, <span class="number">1</span>, <span class="number">-2.4</span>, <span class="number">0</span>, SOLID);</span><br><span class="line">	drawSkewed(<span class="number">1.2</span>, <span class="number">3</span>, <span class="number">2</span>, <span class="number">-1</span>, <span class="number">-2.4</span>, <span class="number">0</span>, SOLID);</span><br><span class="line">	<span class="comment">//脚</span></span><br><span class="line">	drawSkewed(<span class="number">1.5</span>, <span class="number">1</span>, <span class="number">3</span>, <span class="number">0.9</span>, <span class="number">-9.2</span>, <span class="number">0</span>, SOLID);</span><br><span class="line">	drawSkewed(<span class="number">1.5</span>, <span class="number">1</span>, <span class="number">3</span>, <span class="number">-0.9</span>, <span class="number">-9.2</span>, <span class="number">0</span>, SOLID);</span><br><span class="line">	glPopMatrix();</span><br><span class="line">    glutSwapBuffers();</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//鼠标点击事件</span></span><br><span class="line"><span class="built_in">void</span> mouseClick(<span class="built_in">int</span> btn, <span class="built_in">int</span> state, <span class="built_in">int</span> x, <span class="built_in">int</span> y) &#123;</span><br><span class="line">    moveX = x;</span><br><span class="line">	moveY = y;</span><br><span class="line">	GLfloat ambient[] = &#123; (<span class="built_in">float</span>)rand() / RAND_MAX, (<span class="built_in">float</span>)rand() / RAND_MAX, (<span class="built_in">float</span>)rand() / RAND_MAX, <span class="number">0.1</span> &#125;;  </span><br><span class="line">	 <span class="comment">//设置环境光</span></span><br><span class="line">	glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);  </span><br><span class="line">	<span class="comment">//启用光源</span></span><br><span class="line">	glEnable(GL_LIGHT0);  </span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//键盘事件</span></span><br><span class="line"><span class="built_in">void</span> keyPressed(unsigned char key, <span class="built_in">int</span> x, <span class="built_in">int</span> y) &#123;</span><br><span class="line">    <span class="keyword">switch</span> (key) &#123;</span><br><span class="line">    <span class="keyword">case</span> <span class="string">'a'</span>:</span><br><span class="line">        spinX -= <span class="number">2</span>;</span><br><span class="line">        <span class="keyword">break</span>;</span><br><span class="line">    <span class="keyword">case</span> <span class="string">'d'</span>:</span><br><span class="line">         spinX += <span class="number">2</span>;  </span><br><span class="line">        <span class="keyword">break</span>;</span><br><span class="line">    <span class="keyword">case</span> <span class="string">'w'</span>:</span><br><span class="line">        des += <span class="number">2</span>;</span><br><span class="line">        <span class="keyword">break</span>;</span><br><span class="line">    <span class="keyword">case</span> <span class="string">'s'</span>:</span><br><span class="line">        des -= <span class="number">2</span>;</span><br><span class="line">		<span class="keyword">break</span>;</span><br><span class="line">	&#125;</span><br><span class="line">	glutPostRedisplay();</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 鼠标移动事件 </span></span><br><span class="line"><span class="built_in">void</span> mouseMove(<span class="built_in">int</span> x, <span class="built_in">int</span> y) &#123;</span><br><span class="line">	<span class="built_in">int</span> dx = x - moveX;</span><br><span class="line">	<span class="built_in">int</span> dy = y - moveY;</span><br><span class="line">	printf(<span class="string">"dx;%dx,dy:%dy\n"</span>,dx,dy);</span><br><span class="line">	spinX += dx;</span><br><span class="line">	spinY += dy;</span><br><span class="line">	glutPostRedisplay();</span><br><span class="line">	moveX = x;</span><br><span class="line">	moveY = y;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="built_in">void</span> reshape(<span class="built_in">int</span> w, <span class="built_in">int</span> h) &#123;</span><br><span class="line">	<span class="comment">//定义视口大小</span></span><br><span class="line">	glViewport(<span class="number">0</span>, <span class="number">0</span>, (GLsizei) w, (GLsizei) h); </span><br><span class="line">	<span class="comment">//投影显示</span></span><br><span class="line">	glMatrixMode(GL_PROJECTION);</span><br><span class="line">	<span class="comment">//坐标原点在屏幕中心</span></span><br><span class="line">	glLoadIdentity();</span><br><span class="line">	<span class="comment">//操作模型视景</span></span><br><span class="line">	gluPerspective(<span class="number">60.0</span>, (GLfloat) w/(GLfloat) h, <span class="number">1.0</span>, <span class="number">20.0</span>);</span><br><span class="line">	glMatrixMode(GL_MODELVIEW);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="built_in">int</span> main(<span class="built_in">int</span> argc, char** argv) &#123;</span><br><span class="line">	<span class="comment">//初始化</span></span><br><span class="line">	glutInit(&amp;argc, argv);</span><br><span class="line">	<span class="comment">//设置显示模式</span></span><br><span class="line">	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);</span><br><span class="line">	<span class="comment">//初始化窗口大小</span></span><br><span class="line">	glutInitWindowSize(<span class="number">500</span>, <span class="number">500</span>); </span><br><span class="line">	<span class="comment">//定义左上角窗口位置</span></span><br><span class="line">	glutInitWindowPosition(<span class="number">100</span>, <span class="number">100</span>);</span><br><span class="line">	<span class="comment">//创建窗口</span></span><br><span class="line">	glutCreateWindow(argv[<span class="number">0</span>]);</span><br><span class="line">	<span class="comment">//初始化</span></span><br><span class="line">	init();</span><br><span class="line">	<span class="comment">//显示函数</span></span><br><span class="line">	glutDisplayFunc(display);</span><br><span class="line">	<span class="comment">//窗口大小改变时的响应</span></span><br><span class="line">	glutReshapeFunc(reshape);</span><br><span class="line">	<span class="comment">//鼠标点击事件，鼠标点击或者松开时调用</span></span><br><span class="line">    glutMouseFunc(mouseClick);</span><br><span class="line">	<span class="comment">//鼠标移动事件，鼠标按下并移动时调用</span></span><br><span class="line">    glutMotionFunc(mouseMove);</span><br><span class="line">	<span class="comment">//键盘事件</span></span><br><span class="line">	glutKeyboardFunc(keyPressed);</span><br><span class="line">	<span class="comment">//循环</span></span><br><span class="line">	glutMainLoop();</span><br><span class="line">	<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>仅供参考，如有问题，敬请指正。 运行结果如下 <a href="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/06/QQ截图20150607013139.jpg" target="_blank" rel="noopener"><img src="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/06/QQ截图20150607013139.jpg" alt="QQ截图20150607013139"></a> 恩，大体就是这样。</p>
                  <h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2>
                  <p>本次实验做的比较匆忙，只研究了一个晚上的时间，所以有些地方还是不太完善，希望发出来对小伙伴们有所启发，有所帮助。如果有问题，欢迎同我交流。谢大家！</p>
                  </p>
                </div>
              </div>
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-user"></i>
                  </span>
                  <span class="post-meta-item-text">作者</span>
                  <span><a href="/authors/崔庆才" class="author" itemprop="url" rel="index">崔庆才</a></span>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>
                  <time title="创建时间：2015-06-07 01:35:13" itemprop="dateCreated datePublished" datetime="2015-06-07T01:35:13+08:00">2015-06-07</time>
                </span>
                <span id="/1867.html" class="post-meta-item leancloud_visitors" data-flag-title="OpenGL绘图实例十之绘制3D机器人" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="fa fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
                <span class="post-meta-item" title="本文字数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-file-word"></i>
                  </span>
                  <span class="post-meta-item-text">本文字数：</span>
                  <span>9.5k</span>
                </span>
                <span class="post-meta-item" title="阅读时长">
                  <span class="post-meta-item-icon">
                    <i class="far fa-clock"></i>
                  </span>
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                  <span>9 分钟</span>
                </span>
              </div>
            </article>
            <article itemscope itemtype="http://schema.org/Article" class="post-block index" lang="zh-CN">
              <link itemprop="mainEntityOfPage" href="https://cuiqingcai.com/1860.html">
              <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
                <meta itemprop="image" content="/images/avatar.png">
                <meta itemprop="name" content="崔庆才">
                <meta itemprop="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
              </span>
              <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
                <meta itemprop="name" content="静觅">
              </span>
              <header class="post-header">
                <h2 class="post-title" itemprop="name headline">
                  <a class="label"> C/C++ <i class="label-arrow"></i>
                  </a>
                  <a href="/1860.html" class="post-title-link" itemprop="url">OpenGL绘图实例九之3D绘图基础</a>
                </h2>
              </header>
              <div class="post-body" itemprop="articleBody">
                <div class="thumb">
                  <img itemprop="contentUrl" class="random">
                </div>
                <div class="excerpt">
                  <p>
                  <h2 id="综述"><a href="#综述" class="headerlink" title="综述"></a>综述</h2>
                  <p>在前面我们进行了2D图形的绘制，接下来，我们将步入3D图形的世界，绘制出一个3D机器人，好，废话不多说，让我们一起来迈入3D绘图之旅吧。</p>
                  <h2 id="基本函数"><a href="#基本函数" class="headerlink" title="基本函数"></a>基本函数</h2>
                  <p>那么在绘图之前呢，我们首先要介绍几个新的函数，弄懂了这几个函数我们才能方便地绘制出我们的3D机器人。 那么我们介绍一下<strong>gluPerspective</strong>、<strong>gluLookAt、glPushMatrix、glPopMatrix()函数</strong></p>
                  <h3 id="1-void-gluPerspective-GLdouble-fovy-GLdouble-aspect-GLdouble-zNear-GLdouble-zFar"><a href="#1-void-gluPerspective-GLdouble-fovy-GLdouble-aspect-GLdouble-zNear-GLdouble-zFar" class="headerlink" title="1.void gluPerspective(GLdouble fovy,GLdouble aspect,GLdouble zNear,GLdouble zFar)"></a>1.void gluPerspective(GLdouble fovy,GLdouble aspect,GLdouble zNear,GLdouble zFar)</h3>
                  <p>参数说明： fovy，视角的大小，如果设置为0,相当闭上眼睛，什么也看不到，如果为180，则可以看到几乎所有的内容。一般设置为60即可。 aspect，就是实际窗口的纵横比,即x/y，一般都是要按照窗口比例来，否则看到的图形和实际图形就会不一样了。 zNear，表示近处的裁面。 zFar，表示远处的裁面。 gluPerspective这个函数指定了观察的视景体在世界坐标系中的具体大小，一般而言，其中的参数aspect应该与窗口的宽高比大小相同。比如说，aspect=2.0表示在观察者的角度中物体的宽度是高度的两倍，在视口中宽度也是高度的两倍，这样显示出的物体才不会被扭曲。 <a href="http://baike.baidu.com/link?url=jzTDJ5fxVoKMTgijgmszkzuPR6116C5DC4GETFIRZvBajy3dWAB539r3oMsoXpTKCxTksLImx1J2VSC5Q-zJja" target="_blank" rel="noopener">详细说明</a> <a href="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/06/03087bf40ad162d9f337731d11dfa9ec8b13cdd1.jpg" target="_blank" rel="noopener"><img src="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/06/03087bf40ad162d9f337731d11dfa9ec8b13cdd1.jpg" alt="03087bf40ad162d9f337731d11dfa9ec8b13cdd1"></a> </p>
                  <h3 id="2-void-gluLookAt-GLdouble-eyex-GLdouble-eyey-GLdouble-eyez-GLdouble-centerx-GLdouble-centery-GLdouble-centerz-GLdouble-upx-GLdouble-upy-GLdouble-upz"><a href="#2-void-gluLookAt-GLdouble-eyex-GLdouble-eyey-GLdouble-eyez-GLdouble-centerx-GLdouble-centery-GLdouble-centerz-GLdouble-upx-GLdouble-upy-GLdouble-upz" class="headerlink" title="2.void gluLookAt(GLdouble eyex,GLdouble eyey,GLdouble eyez,GLdouble centerx,GLdouble centery,GLdouble centerz,GLdouble upx,GLdouble upy,GLdouble upz)"></a><strong>2.void gluLookAt(GLdouble eyex,GLdouble eyey,GLdouble eyez,GLdouble centerx,GLdouble centery,GLdouble centerz,GLdouble upx,GLdouble upy,GLdouble upz)</strong></h3>
                  <p>该函数定义一个视图矩阵，并与当前矩阵相乘。</p>
                  <p>第一组eyex, eyey,eyez 相机在世界坐标的位置</p>
                  <p>第二组centerx,centery,centerz 相机镜头对准的物体在世界坐标的位置</p>
                  <p>第三组upx,upy,upz 相机向上的方向在世界坐标中的方向</p>
                  <p>你把相机想象成为你自己的脑袋：</p>
                  <p>第一组数据就是脑袋的位置</p>
                  <p>第二组数据就是眼睛看的物体的位置</p>
                  <p>第三组就是头顶朝向的方向（因为你可以歪着头看同一个物体）</p>
                  <p>在这里，我们就涉及到一个十分重要的概念，坐标系。 在3D绘图中，坐标系是右手系，如果x轴指向我们的右侧，那么y则指向上侧，z轴指向屏幕外。如下图所示。 <a href="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/06/20150606234046.jpg" target="_blank" rel="noopener"><img src="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/06/20150606234046.jpg" alt="20150606234046"></a> 理解了上述两个函数，下面我们来用一个小例子感受一下 运行如下代码</p>
                  <figure class="highlight angelscript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">#include &lt;glut.h&gt;</span><br><span class="line">#include &lt;stdlib.h&gt;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="built_in">void</span> display(<span class="built_in">void</span>) &#123;</span><br><span class="line">	<span class="comment">//清除缓冲区颜色</span></span><br><span class="line">	glClear(GL_COLOR_BUFFER_BIT);</span><br><span class="line">	<span class="comment">//定义白色</span></span><br><span class="line">	glColor3f(<span class="number">1.0</span>, <span class="number">1.0</span>, <span class="number">1.0</span>); </span><br><span class="line">	<span class="comment">//圆点放坐标中心</span></span><br><span class="line">	glLoadIdentity();  </span><br><span class="line">	<span class="comment">//从哪个地方看</span></span><br><span class="line">	gluLookAt(<span class="number">0.0</span>, <span class="number">0.0</span>, <span class="number">5.0</span>, <span class="number">0.0</span>, <span class="number">0.0</span>, <span class="number">0.0</span>, <span class="number">0.0</span>, <span class="number">1.0</span>, <span class="number">0.0</span>);</span><br><span class="line">	glutWireTeapot(<span class="number">2</span>);</span><br><span class="line">    <span class="comment">//清除缓冲区刷新</span></span><br><span class="line">    glutSwapBuffers();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="built_in">void</span> reshape(<span class="built_in">int</span> w, <span class="built_in">int</span> h) &#123;</span><br><span class="line">	<span class="comment">//定义视口大小</span></span><br><span class="line">	glViewport(<span class="number">0</span>, <span class="number">0</span>, (GLsizei) w, (GLsizei) h); </span><br><span class="line">	<span class="comment">//投影显示</span></span><br><span class="line">	glMatrixMode(GL_PROJECTION);</span><br><span class="line">	<span class="comment">//坐标原点在屏幕中心</span></span><br><span class="line">	glLoadIdentity();</span><br><span class="line">	<span class="comment">//操作模型视景</span></span><br><span class="line">	gluPerspective(<span class="number">60.0</span>, (GLfloat) w/(GLfloat) h, <span class="number">1.0</span>, <span class="number">20.0</span>);</span><br><span class="line">	glMatrixMode(GL_MODELVIEW);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="built_in">int</span> main(<span class="built_in">int</span> argc, char** argv) &#123;</span><br><span class="line">	<span class="comment">//初始化</span></span><br><span class="line">	glutInit(&amp;argc, argv);</span><br><span class="line">	<span class="comment">//设置显示模式</span></span><br><span class="line">	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);</span><br><span class="line">	<span class="comment">//初始化窗口大小</span></span><br><span class="line">	glutInitWindowSize(<span class="number">500</span>, <span class="number">500</span>); </span><br><span class="line">	<span class="comment">//定义左上角窗口位置</span></span><br><span class="line">	glutInitWindowPosition(<span class="number">100</span>, <span class="number">100</span>);</span><br><span class="line">	<span class="comment">//创建窗口</span></span><br><span class="line">	glutCreateWindow(argv[<span class="number">0</span>]);</span><br><span class="line">	<span class="comment">//清除颜色缓冲区</span></span><br><span class="line">	glClearColor(<span class="number">0.0</span>, <span class="number">0.0</span>, <span class="number">0.0</span>, <span class="number">0.0</span>); </span><br><span class="line">	<span class="comment">//显示函数</span></span><br><span class="line">	glutDisplayFunc(display);</span><br><span class="line">	<span class="comment">//窗口大小改变时的响应</span></span><br><span class="line">	glutReshapeFunc(reshape);</span><br><span class="line">	<span class="comment">//循环</span></span><br><span class="line">	glutMainLoop();</span><br><span class="line">	<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>运行结果如下 <a href="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/06/QQ截图20150606234448.jpg" target="_blank" rel="noopener"><img src="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/06/QQ截图20150606234448.jpg" alt="QQ截图20150606234448"></a> 在这里，我们定义了</p>
                  <figure class="highlight angelscript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">gluLookAt(<span class="number">0.0</span>, <span class="number">0.0</span>, <span class="number">5.0</span>, <span class="number">0.0</span>, <span class="number">0.0</span>, <span class="number">0.0</span>, <span class="number">0.0</span>, <span class="number">1.0</span>, <span class="number">0.0</span>);</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>意思就是把我们的眼睛放到了（0,0,5）的位置，茶壶放到了原点，脑袋顶朝上，即正视茶壶。 如果我们改变了几个参数的值，例如</p>
                  <figure class="highlight angelscript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">gluLookAt(<span class="number">0.0</span>, <span class="number">0.0</span>, <span class="number">5.0</span>, <span class="number">4.0</span>, <span class="number">1.0</span>, <span class="number">0.0</span>, <span class="number">0.0</span>, <span class="number">0.0</span>, <span class="number">1.0</span>);</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>眼睛位置不变，茶壶位置变为（4,1,0），脑袋顶的方向朝屏幕外侧，那么看到的效果如下。 <a href="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/06/QQ截图20150606234708.jpg" target="_blank" rel="noopener"><img src="http://qiniu.cuiqingcai.com/wp-content/uploads/2015/06/QQ截图20150606234708.jpg" alt="QQ截图20150606234708"></a> 大家可以通过更改这些参数的值来对视图进行变换。</p>
                  <h3 id="3-glPushMatrix-、glPopMatrix"><a href="#3-glPushMatrix-、glPopMatrix" class="headerlink" title="3.glPushMatrix()、glPopMatrix()"></a>3.glPushMatrix()、glPopMatrix()</h3>
                  <p>这个方法在绘制3D图形时依然十分有用，因为我们需要绘制好多个图形，绘制多个不一样的图形必然要经过各种矩阵变换，所以，少不了的利用平移变换放缩的功能，所以为了保证每个图形不受影响，在绘制一个新图形前我们只要调用一下glPushMatrix函数，保存当前的变换矩阵，然后绘制完一个图形之后再调用glPopMatrix函数来恢复之前的变换矩阵就可以了。 比如，绘制球体</p>
                  <figure class="highlight reasonml">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">gl<span class="constructor">PushMatrix()</span>;</span><br><span class="line">gl<span class="constructor">Translated(<span class="params">x</span>,<span class="params">y</span>,<span class="params">z</span>)</span>;</span><br><span class="line">glut<span class="constructor">WireSphere(R,20,20)</span>;</span><br><span class="line">gl<span class="constructor">PopMatrix()</span>;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>在两个函数中间我们可以进行任意的变换放缩等操作，然后绘制想要的图形即可。</p>
                  <h2 id="绘图函数"><a href="#绘图函数" class="headerlink" title="绘图函数"></a>绘图函数</h2>
                  <p>接下来我们说一下一些常用的绘图函数，直接用类库函数来绘制即可。</p>
                  <figure class="highlight reasonml">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">void glut<span class="constructor">WireSphere(GLdouble <span class="params">radius</span>, GLint <span class="params">slices</span>, GLint <span class="params">stacks</span>)</span>; 线框球</span><br><span class="line">void glut<span class="constructor">SolidSphere(GLdouble <span class="params">radius</span>, GLint <span class="params">slices</span>, GLint <span class="params">stacks</span>)</span>; 实心球</span><br><span class="line">void glut<span class="constructor">WireCube(GLdouble <span class="params">size</span>)</span>; 线框立方体</span><br><span class="line">void glut<span class="constructor">SolidCube(GLdouble <span class="params">size</span>)</span>; 实心立方体</span><br><span class="line">void glut<span class="constructor">WireTorus(GLdouble <span class="params">innerRadius</span>, GLdouble <span class="params">outerRadius</span>, GLint <span class="params">nsides</span>, GLint <span class="params">rings</span>)</span>; 线框圆环</span><br><span class="line">void glut<span class="constructor">SolidTorus(GLdouble <span class="params">innerRadius</span>, GLdouble <span class="params">outerRadius</span>, GLint <span class="params">nsides</span>, GLint <span class="params">rings</span>)</span>; 实心圆环</span><br><span class="line">void glut<span class="constructor">WireIcosahedron(<span class="params">void</span>)</span>; 线框<span class="number">20</span>面体</span><br><span class="line">void glut<span class="constructor">SolidIcosahedron(<span class="params">void</span>)</span>; 实心<span class="number">20</span>面体</span><br><span class="line">void glut<span class="constructor">WireOctahedron(<span class="params">void</span>)</span>; 线框<span class="number">8</span>面体 </span><br><span class="line">void glut<span class="constructor">SolidOctahedron(<span class="params">void</span>)</span>; 实心<span class="number">8</span>面体</span><br><span class="line">void glut<span class="constructor">WireTetrahedron(<span class="params">void</span>)</span>; 线框<span class="number">4</span>面体</span><br><span class="line">void glut<span class="constructor">SolidTetrahedron(<span class="params">void</span>)</span>; 实心<span class="number">4</span>面体</span><br><span class="line">void glut<span class="constructor">WireDodecahedron(GLdouble <span class="params">radius</span>)</span>; 线框<span class="number">12</span>面体</span><br><span class="line">void glut<span class="constructor">SolidDodecahedron(GLdouble <span class="params">radius</span>)</span>; 实心<span class="number">12</span>面体</span><br><span class="line">void glut<span class="constructor">WireCone(GLdouble <span class="params">radius</span>, GLdouble <span class="params">height</span>, GLint <span class="params">slices</span>, GLint <span class="params">stacks</span>)</span>; 线框圆锥体</span><br><span class="line">void glut<span class="constructor">SolidCone(GLdouble <span class="params">radius</span>, GLdouble <span class="params">height</span>, GLint <span class="params">slices</span>, GLint <span class="params">stacks</span>)</span>; 实心圆锥体</span><br><span class="line">void glut<span class="constructor">WireTeapot(GLdouble <span class="params">size</span>)</span>; 线框茶壶</span><br><span class="line">void glut<span class="constructor">SolidTeapot(GLdouble <span class="params">size</span>)</span>; 实心茶壶</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>利用上面的绘图函数我们便可以方便地实现各种图形的绘制。</p>
                  <h2 id="结语"><a href="#结语" class="headerlink" title="结语"></a>结语</h2>
                  <p>那么本节就先告一段落，本节介绍了相关的绘图函数以及几个重要的函数，为接下来我们绘制机器人做下铺垫，希望小伙伴们可以好好理解。</p>
                  </p>
                </div>
              </div>
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-user"></i>
                  </span>
                  <span class="post-meta-item-text">作者</span>
                  <span><a href="/authors/崔庆才" class="author" itemprop="url" rel="index">崔庆才</a></span>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>
                  <time title="创建时间：2015-06-07 00:27:30" itemprop="dateCreated datePublished" datetime="2015-06-07T00:27:30+08:00">2015-06-07</time>
                </span>
                <span id="/1860.html" class="post-meta-item leancloud_visitors" data-flag-title="OpenGL绘图实例九之3D绘图基础" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="fa fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
                <span class="post-meta-item" title="本文字数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-file-word"></i>
                  </span>
                  <span class="post-meta-item-text">本文字数：</span>
                  <span>3.6k</span>
                </span>
                <span class="post-meta-item" title="阅读时长">
                  <span class="post-meta-item-icon">
                    <i class="far fa-clock"></i>
                  </span>
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                  <span>3 分钟</span>
                </span>
              </div>
            </article>
            <article itemscope itemtype="http://schema.org/Article" class="post-block index" lang="zh-CN">
              <link itemprop="mainEntityOfPage" href="https://cuiqingcai.com/1853.html">
              <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
                <meta itemprop="image" content="/images/avatar.png">
                <meta itemprop="name" content="崔庆才">
                <meta itemprop="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
              </span>
              <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
                <meta itemprop="name" content="静觅">
              </span>
              <header class="post-header">
                <h2 class="post-title" itemprop="name headline">
                  <a class="label"> PHP <i class="label-arrow"></i>
                  </a>
                  <a href="/1853.html" class="post-title-link" itemprop="url">将普通文本替换为正常HTML文本的方法</a>
                </h2>
              </header>
              <div class="post-body" itemprop="articleBody">
                <div class="thumb">
                  <img itemprop="contentUrl" class="random">
                </div>
                <div class="excerpt">
                  <p>
                  <h2 id="综述"><a href="#综述" class="headerlink" title="综述"></a>综述</h2>
                  <p>有时我们在textarea中输入了正常的文本内容，然而如果直接将文本取出来呈现在网页中，原本的换行和回车功能便会失效，完全丢失了原来的样式，这是因为在HTML中的空格和换行分别为&nbsp;和<br>，所以我们需要将其替换才能变成我们想要的样式。 注：本篇内容非常基础，仅作参考，不喜勿喷。</p>
                  <h2 id="替换函数"><a href="#替换函数" class="headerlink" title="替换函数"></a>替换函数</h2>
                  <p>我们可以定义这样的一个函数，将原来的字符串替换为HTML文本。即把空格和换行替换掉即可</p>
                  <figure class="highlight php">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">htmtocode</span><span class="params">($content)</span> </span>&#123; </span><br><span class="line">		$content = htmlspecialchars($content, ENT_QUOTES);</span><br><span class="line">	    $content = str_replace(<span class="string">" "</span>, <span class="string">"&amp;nbsp;"</span>, $content); </span><br><span class="line">	    $content = str_replace(<span class="string">"\n"</span>, <span class="string">"&lt;br&gt;"</span>,$content);    </span><br><span class="line">	    <span class="keyword">return</span> $content; </span><br><span class="line">	&#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>通过上述方法，我们首先将HTML的特殊标记转化，然后替换掉空格和换行即可。</p>
                  <h2 id="用法"><a href="#用法" class="headerlink" title="用法"></a>用法</h2>
                  <p>写个最简单的小例子，在textarea中输入任意的文本，存储到数据库，然后再取出来，可以实现textarea输入的效果，完全一样。 数据库名称：demo 数据库表：</p>
                  <figure class="highlight n1ql">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="keyword">CREATE</span> TABLE <span class="keyword">IF</span> <span class="keyword">NOT</span> <span class="keyword">EXISTS</span> <span class="symbol">`article`</span> (</span><br><span class="line">  <span class="symbol">`id`</span> int(<span class="number">11</span>) <span class="keyword">NOT</span> <span class="literal">NULL</span> AUTO_INCREMENT,</span><br><span class="line">  <span class="symbol">`text`</span> text <span class="keyword">NOT</span> <span class="literal">NULL</span>,</span><br><span class="line">  <span class="keyword">PRIMARY</span> <span class="keyword">KEY</span> (<span class="symbol">`id`</span>)</span><br><span class="line">)</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>插入数据：</p>
                  <figure class="highlight xml">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">"utf-8"</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">form</span> <span class="attr">action</span>=<span class="string">""</span> <span class="attr">method</span>=<span class="string">"post"</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">textarea</span> <span class="attr">name</span>=<span class="string">"text"</span>&gt;</span><span class="tag">&lt;/<span class="name">textarea</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">"submit"</span> <span class="attr">name</span>=<span class="string">"sub"</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;/<span class="name">form</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="php"><span class="meta">&lt;?php</span> </span></span><br><span class="line"><span class="php">	$con = mysql_connect(<span class="string">"localhost"</span>, <span class="string">"root"</span>, <span class="string">""</span>);</span></span><br><span class="line"><span class="php">	<span class="keyword">if</span> (!$con) &#123;</span></span><br><span class="line"><span class="php">		<span class="keyword">die</span>(<span class="string">"数据库连接失败"</span>);</span></span><br><span class="line"><span class="php">	&#125; </span></span><br><span class="line"><span class="php">	mysql_select_db(<span class="string">"demo"</span>,$con);</span></span><br><span class="line"><span class="php">	mysql_query(<span class="string">"set names utf8"</span>);</span></span><br><span class="line"><span class="php">	$text = @$_POST[<span class="string">'text'</span>];</span></span><br><span class="line"><span class="php">	$sql = <span class="string">"insert into article(text) values ('$text')"</span>;</span></span><br><span class="line"><span class="php">	<span class="keyword">echo</span> $sql;</span></span><br><span class="line"><span class="php">	$result = mysql_query($sql,$con);</span></span><br><span class="line"><span class="php">	<span class="keyword">if</span> ($result) &#123;</span></span><br><span class="line"><span class="php">		<span class="keyword">echo</span> <span class="string">"录入成功"</span>;</span></span><br><span class="line"><span class="php">	&#125; <span class="keyword">else</span> &#123;</span></span><br><span class="line"><span class="php">		<span class="keyword">echo</span> <span class="string">"录入失败"</span>;</span></span><br><span class="line"><span class="php">	&#125;</span></span><br><span class="line"></span><br><span class="line"><span class="php"><span class="meta">?&gt;</span></span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>查询数据：</p>
                  <figure class="highlight xml">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">"utf-8"</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">form</span> <span class="attr">action</span>=<span class="string">""</span> <span class="attr">method</span>=<span class="string">"post"</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">textarea</span> <span class="attr">name</span>=<span class="string">"text"</span>&gt;</span><span class="tag">&lt;/<span class="name">textarea</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">"submit"</span> <span class="attr">name</span>=<span class="string">"sub"</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;/<span class="name">form</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="php"><span class="meta">&lt;?php</span> </span></span><br><span class="line"><span class="php">	$con = mysql_connect(<span class="string">"localhost"</span>, <span class="string">"root"</span>, <span class="string">""</span>);</span></span><br><span class="line"><span class="php">	<span class="keyword">if</span> (!$con) &#123;</span></span><br><span class="line"><span class="php">		<span class="keyword">die</span>(<span class="string">"数据库连接失败"</span>);</span></span><br><span class="line"><span class="php">	&#125; </span></span><br><span class="line"><span class="php">	mysql_select_db(<span class="string">"demo"</span>,$con);</span></span><br><span class="line"><span class="php">	mysql_query(<span class="string">"set names utf8"</span>);</span></span><br><span class="line"><span class="php">	$text = @$_POST[<span class="string">'text'</span>];</span></span><br><span class="line"><span class="php">	$sql = <span class="string">"select * from article"</span>;</span></span><br><span class="line"></span><br><span class="line"><span class="php">	$result = mysql_query($sql,$con);</span></span><br><span class="line"><span class="php">	<span class="keyword">if</span> ($result) &#123;</span></span><br><span class="line"><span class="php">		<span class="keyword">while</span> ($row = mysql_fetch_array($result)) &#123;</span></span><br><span class="line"><span class="php">			<span class="keyword">echo</span> htmtocode($row[<span class="string">'text'</span>]);</span></span><br><span class="line"><span class="php">		&#125;</span></span><br><span class="line"><span class="php">	&#125; <span class="keyword">else</span> &#123;</span></span><br><span class="line"><span class="php">		<span class="keyword">echo</span> <span class="string">"录入失败"</span>;</span></span><br><span class="line"><span class="php">	&#125;</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="php">	<span class="function"><span class="keyword">function</span> <span class="title">htmtocode</span><span class="params">($content)</span> </span>&#123; </span></span><br><span class="line"><span class="php">		$content = htmlspecialchars($content, ENT_QUOTES);</span></span><br><span class="line"><span class="php">	    $content = str_replace(<span class="string">" "</span>, <span class="string">"&amp;nbsp;"</span>, $content); </span></span><br><span class="line"><span class="php">	    $content = str_replace(<span class="string">"\n"</span>, <span class="string">"&lt;br&gt;"</span>,$content);    </span></span><br><span class="line"><span class="php">	    <span class="keyword">return</span> $content; </span></span><br><span class="line"><span class="php">	&#125;</span></span><br><span class="line"><span class="php"><span class="meta">?&gt;</span></span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>嗯，通过上面的方法我们便可以正常地实现输入内容和输出内容的匹配呈现。</p>
                  </p>
                </div>
              </div>
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-user"></i>
                  </span>
                  <span class="post-meta-item-text">作者</span>
                  <span><a href="/authors/崔庆才" class="author" itemprop="url" rel="index">崔庆才</a></span>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>
                  <time title="创建时间：2015-06-05 22:12:03" itemprop="dateCreated datePublished" datetime="2015-06-05T22:12:03+08:00">2015-06-05</time>
                </span>
                <span id="/1853.html" class="post-meta-item leancloud_visitors" data-flag-title="将普通文本替换为正常HTML文本的方法" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="fa fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
                <span class="post-meta-item" title="本文字数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-file-word"></i>
                  </span>
                  <span class="post-meta-item-text">本文字数：</span>
                  <span>2k</span>
                </span>
                <span class="post-meta-item" title="阅读时长">
                  <span class="post-meta-item-icon">
                    <i class="far fa-clock"></i>
                  </span>
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                  <span>2 分钟</span>
                </span>
              </div>
            </article>
            <script>
              document.querySelectorAll('.random').forEach(item => item.src = "https://picsum.photos/id/" + Math.floor(Math.random() * Math.floor(300)) + "/200/133")

            </script>
            <nav class="pagination">
              <a class="extend prev" rel="prev" href="/page/24/"><i class="fa fa-angle-left" aria-label="上一页"></i></a><a class="page-number" href="/">1</a><span class="space">&hellip;</span><a class="page-number" href="/page/24/">24</a><span class="page-number current">25</span><a class="page-number" href="/page/26/">26</a><span class="space">&hellip;</span><a class="page-number" href="/page/31/">31</a><a class="extend next" rel="next" href="/page/26/"><i class="fa fa-angle-right" aria-label="下一页"></i></a>
            </nav>
          </div>
          <script>
            window.addEventListener('tabs:register', () =>
            {
              let
              {
                activeClass
              } = CONFIG.comments;
              if (CONFIG.comments.storage)
              {
                activeClass = localStorage.getItem('comments_active') || activeClass;
              }
              if (activeClass)
              {
                let activeTab = document.querySelector(`a[href="#comment-${activeClass}"]`);
                if (activeTab)
                {
                  activeTab.click();
                }
              }
            });
            if (CONFIG.comments.storage)
            {
              window.addEventListener('tabs:click', event =>
              {
                if (!event.target.matches('.tabs-comment .tab-content .tab-pane')) return;
                let commentClass = event.target.classList[1];
                localStorage.setItem('comments_active', commentClass);
              });
            }

          </script>
        </div>
        <div class="toggle sidebar-toggle">
          <span class="toggle-line toggle-line-first"></span>
          <span class="toggle-line toggle-line-middle"></span>
          <span class="toggle-line toggle-line-last"></span>
        </div>
        <aside class="sidebar">
          <div class="sidebar-inner">
            <ul class="sidebar-nav motion-element">
              <li class="sidebar-nav-toc"> 文章目录 </li>
              <li class="sidebar-nav-overview"> 站点概览 </li>
            </ul>
            <!--noindex-->
            <div class="post-toc-wrap sidebar-panel">
            </div>
            <!--/noindex-->
            <div class="site-overview-wrap sidebar-panel">
              <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
                <img class="site-author-image" itemprop="image" alt="崔庆才" src="/images/avatar.png">
                <p class="site-author-name" itemprop="name">崔庆才</p>
                <div class="site-description" itemprop="description">崔庆才的个人站点，记录生活的瞬间，分享学习的心得。</div>
              </div>
              <div class="site-state-wrap motion-element">
                <nav class="site-state">
                  <div class="site-state-item site-state-posts">
                    <a href="/archives/">
                      <span class="site-state-item-count">608</span>
                      <span class="site-state-item-name">日志</span>
                    </a>
                  </div>
                  <div class="site-state-item site-state-categories">
                    <a href="/categories/">
                      <span class="site-state-item-count">24</span>
                      <span class="site-state-item-name">分类</span></a>
                  </div>
                  <div class="site-state-item site-state-tags">
                    <a href="/tags/">
                      <span class="site-state-item-count">156</span>
                      <span class="site-state-item-name">标签</span></a>
                  </div>
                </nav>
              </div>
              <div class="links-of-author motion-element">
                <span class="links-of-author-item">
                  <a href="https://github.com/Germey" title="GitHub → https:&#x2F;&#x2F;github.com&#x2F;Germey" rel="noopener" target="_blank"><i class="fab fa-github fa-fw"></i>GitHub</a>
                </span>
                <span class="links-of-author-item">
                  <a href="mailto:cqc@cuiqingcai.com.com" title="邮件 → mailto:cqc@cuiqingcai.com.com" rel="noopener" target="_blank"><i class="fa fa-envelope fa-fw"></i>邮件</a>
                </span>
                <span class="links-of-author-item">
                  <a href="https://weibo.com/cuiqingcai" title="微博 → https:&#x2F;&#x2F;weibo.com&#x2F;cuiqingcai" rel="noopener" target="_blank"><i class="fab fa-weibo fa-fw"></i>微博</a>
                </span>
                <span class="links-of-author-item">
                  <a href="https://www.zhihu.com/people/Germey" title="知乎 → https:&#x2F;&#x2F;www.zhihu.com&#x2F;people&#x2F;Germey" rel="noopener" target="_blank"><i class="fa fa-magic fa-fw"></i>知乎</a>
                </span>
              </div>
            </div>
            <div style=" width: 100%;" class="sidebar-panel sidebar-panel-image sidebar-panel-active">
              <a href="https://tutorial.lengyue.video/?coupon=12ef4b1a-a3db-11ea-bb37-0242ac130002_cqx_850" target="_blank" rel="noopener">
                <img src="https://qiniu.cuiqingcai.com/bco2a.png" style=" width: 100%;">
              </a>
            </div>
            <div style=" width: 100%;" class="sidebar-panel sidebar-panel-image sidebar-panel-active">
              <a href="http://www.ipidea.net/?utm-source=cqc&utm-keyword=?cqc" target="_blank" rel="noopener">
                <img src="https://qiniu.cuiqingcai.com/0ywun.png" style=" width: 100%;">
              </a>
            </div>
            <div class="sidebar-panel sidebar-panel-tags sidebar-panel-active">
              <h4 class="name"> 标签云 </h4>
              <div class="content">
                <a href="/tags/2048/" style="font-size: 10px;">2048</a> <a href="/tags/API/" style="font-size: 10px;">API</a> <a href="/tags/Bootstrap/" style="font-size: 11.25px;">Bootstrap</a> <a href="/tags/CDN/" style="font-size: 10px;">CDN</a> <a href="/tags/CQC/" style="font-size: 10px;">CQC</a> <a href="/tags/CSS/" style="font-size: 10px;">CSS</a> <a href="/tags/CSS-%E5%8F%8D%E7%88%AC%E8%99%AB/" style="font-size: 10px;">CSS 反爬虫</a> <a href="/tags/CV/" style="font-size: 10px;">CV</a> <a href="/tags/Django/" style="font-size: 10px;">Django</a> <a href="/tags/Eclipse/" style="font-size: 11.25px;">Eclipse</a> <a href="/tags/FTP/" style="font-size: 10px;">FTP</a> <a href="/tags/Git/" style="font-size: 10px;">Git</a> <a href="/tags/GitHub/" style="font-size: 13.75px;">GitHub</a> <a href="/tags/HTML5/" style="font-size: 10px;">HTML5</a> <a href="/tags/Hexo/" style="font-size: 10px;">Hexo</a> <a href="/tags/IT/" style="font-size: 10px;">IT</a> <a href="/tags/JSP/" style="font-size: 10px;">JSP</a> <a href="/tags/JavaScript/" style="font-size: 10px;">JavaScript</a> <a href="/tags/K8s/" style="font-size: 10px;">K8s</a> <a href="/tags/LOGO/" style="font-size: 10px;">LOGO</a> <a href="/tags/Linux/" style="font-size: 10px;">Linux</a> <a href="/tags/MIUI/" style="font-size: 10px;">MIUI</a> <a href="/tags/MongoDB/" style="font-size: 10px;">MongoDB</a> <a href="/tags/Mysql/" style="font-size: 10px;">Mysql</a> <a href="/tags/NBA/" style="font-size: 10px;">NBA</a> <a href="/tags/PHP/" style="font-size: 11.25px;">PHP</a> <a href="/tags/PS/" style="font-size: 10px;">PS</a> <a href="/tags/Pathlib/" style="font-size: 10px;">Pathlib</a> <a href="/tags/PhantomJS/" style="font-size: 10px;">PhantomJS</a> <a href="/tags/Python/" style="font-size: 15px;">Python</a> <a href="/tags/Python3/" style="font-size: 12.5px;">Python3</a> <a href="/tags/Pythonic/" style="font-size: 10px;">Pythonic</a> <a href="/tags/QQ/" style="font-size: 10px;">QQ</a> <a href="/tags/Redis/" style="font-size: 10px;">Redis</a> <a href="/tags/SAE/" style="font-size: 10px;">SAE</a> <a href="/tags/SSH/" style="font-size: 10px;">SSH</a> <a href="/tags/SVG/" style="font-size: 10px;">SVG</a> <a href="/tags/Scrapy/" style="font-size: 10px;">Scrapy</a> <a href="/tags/Scrapy-redis/" style="font-size: 10px;">Scrapy-redis</a> <a href="/tags/Scrapy%E5%88%86%E5%B8%83%E5%BC%8F/" style="font-size: 10px;">Scrapy分布式</a> <a href="/tags/Selenium/" style="font-size: 10px;">Selenium</a> <a href="/tags/TKE/" style="font-size: 10px;">TKE</a> <a href="/tags/Ubuntu/" style="font-size: 11.25px;">Ubuntu</a> <a href="/tags/VS-Code/" style="font-size: 10px;">VS Code</a> <a href="/tags/Vs-Code/" style="font-size: 10px;">Vs Code</a> <a href="/tags/Vue/" style="font-size: 11.25px;">Vue</a> <a href="/tags/Webpack/" style="font-size: 10px;">Webpack</a> <a href="/tags/Windows/" style="font-size: 10px;">Windows</a> <a href="/tags/Winpcap/" style="font-size: 10px;">Winpcap</a> <a href="/tags/WordPress/" style="font-size: 13.75px;">WordPress</a> <a href="/tags/Youtube/" style="font-size: 11.25px;">Youtube</a> <a href="/tags/android/" style="font-size: 10px;">android</a> <a href="/tags/ansible/" style="font-size: 10px;">ansible</a> <a href="/tags/cocos2d-x/" style="font-size: 10px;">cocos2d-x</a> <a href="/tags/e6/" style="font-size: 10px;">e6</a> <a href="/tags/fitvids/" style="font-size: 10px;">fitvids</a> <a href="/tags/git/" style="font-size: 11.25px;">git</a> <a href="/tags/json/" style="font-size: 10px;">json</a> <a href="/tags/js%E9%80%86%E5%90%91/" style="font-size: 10px;">js逆向</a> <a href="/tags/kubernetes/" style="font-size: 10px;">kubernetes</a> <a href="/tags/log/" style="font-size: 10px;">log</a> <a href="/tags/logging/" style="font-size: 10px;">logging</a> <a href="/tags/matlab/" style="font-size: 11.25px;">matlab</a> <a href="/tags/python/" style="font-size: 20px;">python</a> <a href="/tags/pytube/" style="font-size: 11.25px;">pytube</a> <a href="/tags/pywin32/" style="font-size: 10px;">pywin32</a> <a href="/tags/style/" style="font-size: 10px;">style</a> <a href="/tags/tomcat/" style="font-size: 10px;">tomcat</a> <a href="/tags/ubuntu/" style="font-size: 10px;">ubuntu</a> <a href="/tags/uwsgi/" style="font-size: 10px;">uwsgi</a> <a href="/tags/vsftpd/" style="font-size: 10px;">vsftpd</a> <a href="/tags/wamp/" style="font-size: 10px;">wamp</a> <a href="/tags/wineQQ/" style="font-size: 10px;">wineQQ</a> <a href="/tags/%E4%B8%83%E7%89%9B/" style="font-size: 11.25px;">七牛</a> <a href="/tags/%E4%B8%8A%E6%B5%B7/" style="font-size: 10px;">上海</a> <a href="/tags/%E4%B8%AA%E4%BA%BA%E7%BD%91%E7%AB%99/" style="font-size: 10px;">个人网站</a> <a href="/tags/%E4%B8%BB%E9%A2%98/" style="font-size: 10px;">主题</a> <a href="/tags/%E4%BA%91%E4%BA%A7%E5%93%81/" style="font-size: 10px;">云产品</a> <a href="/tags/%E4%BA%91%E5%AD%98%E5%82%A8/" style="font-size: 10px;">云存储</a> <a href="/tags/%E4%BA%AC%E4%B8%9C%E4%BA%91/" style="font-size: 10px;">京东云</a> <a href="/tags/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/" style="font-size: 12.5px;">人工智能</a> <a href="/tags/%E4%BB%A3%E7%90%86/" style="font-size: 10px;">代理</a> <a href="/tags/%E4%BB%A3%E7%A0%81/" style="font-size: 10px;">代码</a> <a href="/tags/%E4%BB%A3%E7%A0%81%E5%88%86%E4%BA%AB%E5%9B%BE/" style="font-size: 10px;">代码分享图</a> <a href="/tags/%E4%BC%98%E5%8C%96/" style="font-size: 10px;">优化</a> <a href="/tags/%E4%BD%8D%E8%BF%90%E7%AE%97/" style="font-size: 10px;">位运算</a> <a href="/tags/%E5%85%AC%E4%BC%97%E5%8F%B7/" style="font-size: 10px;">公众号</a> <a href="/tags/%E5%88%86%E4%BA%AB/" style="font-size: 10px;">分享</a> <a href="/tags/%E5%88%86%E5%B8%83%E5%BC%8F/" style="font-size: 10px;">分布式</a> <a href="/tags/%E5%88%9B%E4%B8%9A/" style="font-size: 10px;">创业</a> <a href="/tags/%E5%89%8D%E7%AB%AF/" style="font-size: 12.5px;">前端</a> <a href="/tags/%E5%8D%9A%E5%AE%A2/" style="font-size: 10px;">博客</a> <a href="/tags/%E5%8E%9F%E7%94%9FAPP/" style="font-size: 10px;">原生APP</a> <a href="/tags/%E5%8F%8D%E7%88%AC%E8%99%AB/" style="font-size: 12.5px;">反爬虫</a> <a href="/tags/%E5%91%BD%E4%BB%A4/" style="font-size: 10px;">命令</a> <a href="/tags/%E5%93%8D%E5%BA%94%E5%BC%8F%E5%B8%83%E5%B1%80/" style="font-size: 10px;">响应式布局</a> <a href="/tags/%E5%9E%83%E5%9C%BE%E9%82%AE%E4%BB%B6/" style="font-size: 10px;">垃圾邮件</a> <a href="/tags/%E5%9F%9F%E5%90%8D%E7%BB%91%E5%AE%9A/" style="font-size: 10px;">域名绑定</a> <a href="/tags/%E5%A4%8D%E7%9B%98/" style="font-size: 10px;">复盘</a> <a href="/tags/%E5%A4%A7%E4%BC%97%E7%82%B9%E8%AF%84/" style="font-size: 10px;">大众点评</a> <a href="/tags/%E5%AD%97%E4%BD%93%E5%8F%8D%E7%88%AC%E8%99%AB/" style="font-size: 10px;">字体反爬虫</a> <a href="/tags/%E5%AD%97%E7%AC%A6%E9%97%AE%E9%A2%98/" style="font-size: 10px;">字符问题</a> <a href="/tags/%E5%AD%A6%E4%B9%A0%E6%96%B9%E6%B3%95/" style="font-size: 10px;">学习方法</a> <a href="/tags/%E5%AE%89%E5%8D%93/" style="font-size: 10px;">安卓</a> <a href="/tags/%E5%AE%9E%E7%94%A8/" style="font-size: 10px;">实用</a> <a href="/tags/%E5%B0%81%E9%9D%A2/" style="font-size: 10px;">封面</a> <a href="/tags/%E5%B4%94%E5%BA%86%E6%89%8D/" style="font-size: 18.75px;">崔庆才</a> <a href="/tags/%E5%B7%A5%E5%85%B7/" style="font-size: 12.5px;">工具</a> <a href="/tags/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/" style="font-size: 10px;">开发工具</a> <a href="/tags/%E5%BE%AE%E8%BD%AF/" style="font-size: 10px;">微软</a> <a href="/tags/%E6%80%9D%E8%80%83/" style="font-size: 10px;">思考</a> <a href="/tags/%E6%89%8B%E6%9C%BA%E8%AE%BF%E9%97%AE/" style="font-size: 10px;">手机访问</a> <a href="/tags/%E6%95%99%E7%A8%8B/" style="font-size: 10px;">教程</a> <a href="/tags/%E6%95%99%E8%82%B2/" style="font-size: 10px;">教育</a> <a href="/tags/%E6%96%B0%E4%B9%A6/" style="font-size: 12.5px;">新书</a> <a href="/tags/%E6%96%B9%E6%B3%95%E8%AE%BA/" style="font-size: 10px;">方法论</a> <a href="/tags/%E6%97%85%E6%B8%B8/" style="font-size: 10px;">旅游</a> <a href="/tags/%E6%97%A5%E5%BF%97/" style="font-size: 10px;">日志</a> <a href="/tags/%E6%9A%97%E6%97%B6%E9%97%B4/" style="font-size: 10px;">暗时间</a> <a href="/tags/%E6%9D%9C%E5%85%B0%E7%89%B9/" style="font-size: 11.25px;">杜兰特</a> <a href="/tags/%E6%A1%8C%E9%9D%A2/" style="font-size: 10px;">桌面</a> <a href="/tags/%E6%AD%8C%E5%8D%95/" style="font-size: 10px;">歌单</a> <a href="/tags/%E6%B1%9F%E5%8D%97/" style="font-size: 10px;">江南</a> <a href="/tags/%E6%B8%B8%E6%88%8F/" style="font-size: 10px;">游戏</a> <a href="/tags/%E7%84%A6%E8%99%91/" style="font-size: 10px;">焦虑</a> <a href="/tags/%E7%88%AC%E8%99%AB/" style="font-size: 16.25px;">爬虫</a> <a href="/tags/%E7%88%AC%E8%99%AB%E4%B9%A6%E7%B1%8D/" style="font-size: 11.25px;">爬虫书籍</a> <a href="/tags/%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F/" style="font-size: 10px;">环境变量</a> <a href="/tags/%E7%94%9F%E6%B4%BB%E7%AC%94%E8%AE%B0/" style="font-size: 10px;">生活笔记</a> <a href="/tags/%E7%99%BB%E5%BD%95/" style="font-size: 10px;">登录</a> <a href="/tags/%E7%9F%A5%E4%B9%8E/" style="font-size: 10px;">知乎</a> <a href="/tags/%E7%9F%AD%E4%BF%A1/" style="font-size: 10px;">短信</a> <a href="/tags/%E7%9F%AD%E4%BF%A1%E9%AA%8C%E8%AF%81%E7%A0%81/" style="font-size: 10px;">短信验证码</a> <a href="/tags/%E7%AC%94%E8%AE%B0%E8%BD%AF%E4%BB%B6/" style="font-size: 10px;">笔记软件</a> <a href="/tags/%E7%AF%AE%E7%BD%91/" style="font-size: 10px;">篮网</a> <a href="/tags/%E7%BA%B8%E5%BC%A0/" style="font-size: 10px;">纸张</a> <a href="/tags/%E7%BB%84%E4%BB%B6/" style="font-size: 10px;">组件</a> <a href="/tags/%E7%BD%91%E7%AB%99/" style="font-size: 10px;">网站</a> <a href="/tags/%E7%BD%91%E7%BB%9C%E7%88%AC%E8%99%AB/" style="font-size: 11.25px;">网络爬虫</a> <a href="/tags/%E7%BE%8E%E5%AD%A6/" style="font-size: 10px;">美学</a> <a href="/tags/%E8%82%89%E5%A4%B9%E9%A6%8D/" style="font-size: 10px;">肉夹馍</a> <a href="/tags/%E8%85%BE%E8%AE%AF%E4%BA%91/" style="font-size: 10px;">腾讯云</a> <a href="/tags/%E8%87%AA%E5%BE%8B/" style="font-size: 10px;">自律</a> <a href="/tags/%E8%A5%BF%E5%B0%91%E7%88%B7/" style="font-size: 10px;">西少爷</a> <a href="/tags/%E8%A7%86%E9%A2%91/" style="font-size: 10px;">视频</a> <a href="/tags/%E8%B0%B7%E6%AD%8C%E9%AA%8C%E8%AF%81%E7%A0%81/" style="font-size: 10px;">谷歌验证码</a> <a href="/tags/%E8%BF%90%E8%90%A5/" style="font-size: 10px;">运营</a> <a href="/tags/%E8%BF%9C%E7%A8%8B/" style="font-size: 10px;">远程</a> <a href="/tags/%E9%80%86%E5%90%91/" style="font-size: 10px;">逆向</a> <a href="/tags/%E9%85%8D%E7%BD%AE/" style="font-size: 10px;">配置</a> <a href="/tags/%E9%87%8D%E8%A3%85/" style="font-size: 10px;">重装</a> <a href="/tags/%E9%98%BF%E6%9D%9C/" style="font-size: 10px;">阿杜</a> <a href="/tags/%E9%9D%99%E8%A7%85/" style="font-size: 17.5px;">静觅</a> <a href="/tags/%E9%A2%A0%E8%A6%86/" style="font-size: 10px;">颠覆</a> <a href="/tags/%E9%A3%9E%E4%BF%A1/" style="font-size: 10px;">飞信</a> <a href="/tags/%E9%B8%BF%E8%92%99/" style="font-size: 10px;">鸿蒙</a>
              </div>
              <script>
                const tagsColors = ['#00a67c', '#5cb85c', '#d9534f', '#567e95', '#b37333', '#f4843d', '#15a287']
                const tagsElements = document.querySelectorAll('.sidebar-panel-tags .content a')
                tagsElements.forEach((item) =>
                {
                  item.style.backgroundColor = tagsColors[Math.floor(Math.random() * tagsColors.length)]
                })

              </script>
            </div>
            <div class="sidebar-panel sidebar-panel-categories sidebar-panel-active">
              <h4 class="name"> 分类 </h4>
              <div class="content">
                <ul class="category-list">
                  <li class="category-list-item"><a class="category-list-link" href="/categories/C-C/">C/C++</a><span class="category-list-count">23</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/HTML/">HTML</a><span class="category-list-count">14</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/Java/">Java</a><span class="category-list-count">5</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/JavaScript/">JavaScript</a><span class="category-list-count">26</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/Linux/">Linux</a><span class="category-list-count">15</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/Markdown/">Markdown</a><span class="category-list-count">1</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/Net/">Net</a><span class="category-list-count">4</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/Other/">Other</a><span class="category-list-count">39</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/PHP/">PHP</a><span class="category-list-count">27</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/Paper/">Paper</a><span class="category-list-count">2</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/Python/">Python</a><span class="category-list-count">261</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/TypeScript/">TypeScript</a><span class="category-list-count">2</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/%E4%B8%AA%E4%BA%BA%E5%B1%95%E7%A4%BA/">个人展示</a><span class="category-list-count">1</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/%E4%B8%AA%E4%BA%BA%E6%97%A5%E8%AE%B0/">个人日记</a><span class="category-list-count">9</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/%E4%B8%AA%E4%BA%BA%E8%AE%B0%E5%BD%95/">个人记录</a><span class="category-list-count">4</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/%E4%B8%AA%E4%BA%BA%E9%9A%8F%E7%AC%94/">个人随笔</a><span class="category-list-count">15</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/%E5%AE%89%E8%A3%85%E9%85%8D%E7%BD%AE/">安装配置</a><span class="category-list-count">59</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/%E6%8A%80%E6%9C%AF%E6%9D%82%E8%B0%88/">技术杂谈</a><span class="category-list-count">88</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/%E6%9C%AA%E5%88%86%E7%B1%BB/">未分类</a><span class="category-list-count">1</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/%E7%94%9F%E6%B4%BB%E7%AC%94%E8%AE%B0/">生活笔记</a><span class="category-list-count">1</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/%E7%A6%8F%E5%88%A9%E4%B8%93%E5%8C%BA/">福利专区</a><span class="category-list-count">6</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/%E8%81%8C%E4%BD%8D%E6%8E%A8%E8%8D%90/">职位推荐</a><span class="category-list-count">2</span></li>
                </ul>
              </div>
            </div>
            <div class="sidebar-panel sidebar-panel-friends sidebar-panel-active">
              <h4 class="name"> 友情链接 </h4>
              <ul class="friends">
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/j2dub.jpg">
                  </span>
                  <span class="link">
                    <a href="https://www.findhao.net/" target="_blank" rel="noopener">FindHao</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/ou6mm.jpg">
                  </span>
                  <span class="link">
                    <a href="https://diygod.me/" target="_blank" rel="noopener">DIYgod</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/6apxu.jpg">
                  </span>
                  <span class="link">
                    <a href="https://www.51dev.com/" target="_blank" rel="noopener">IT技术社区</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://www.jankl.com/img/titleshu.jpg">
                  </span>
                  <span class="link">
                    <a href="https://www.jankl.com/" target="_blank" rel="noopener">liberalist</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/bqlbs.png">
                  </span>
                  <span class="link">
                    <a href="http://www.urselect.com/" target="_blank" rel="noopener">优社电商</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/8s88c.jpg">
                  </span>
                  <span class="link">
                    <a href="https://www.yuanrenxue.com/" target="_blank" rel="noopener">猿人学</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/2wgg5.jpg">
                  </span>
                  <span class="link">
                    <a href="https://www.yunlifang.cn/" target="_blank" rel="noopener">云立方</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/shwr6.png">
                  </span>
                  <span class="link">
                    <a href="http://lanbing510.info/" target="_blank" rel="noopener">冰蓝</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/blvoh.jpg">
                  </span>
                  <span class="link">
                    <a href="https://lengyue.me/" target="_blank" rel="noopener">冷月</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="http://qianxunclub.com/favicon.png">
                  </span>
                  <span class="link">
                    <a href="http://qianxunclub.com/" target="_blank" rel="noopener">千寻啊千寻</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/0044u.jpg">
                  </span>
                  <span class="link">
                    <a href="http://kodcloud.com/" target="_blank" rel="noopener">可道云</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/ygnpn.jpg">
                  </span>
                  <span class="link">
                    <a href="http://www.kunkundashen.cn/" target="_blank" rel="noopener">坤坤大神</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/22uv1.png">
                  </span>
                  <span class="link">
                    <a href="http://www.cenchong.com/" target="_blank" rel="noopener">岑冲博客</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/ev9kl.png">
                  </span>
                  <span class="link">
                    <a href="http://www.zxiaoji.com/" target="_blank" rel="noopener">张小鸡</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://www.503error.com/favicon.ico">
                  </span>
                  <span class="link">
                    <a href="https://www.503error.com/" target="_blank" rel="noopener">张志明个人博客</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/x714o.jpg">
                  </span>
                  <span class="link">
                    <a href="http://www.hubwiz.com/" target="_blank" rel="noopener">汇智网</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/129d8.png">
                  </span>
                  <span class="link">
                    <a href="https://www.bysocket.com/" target="_blank" rel="noopener">泥瓦匠BYSocket</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://www.xiongge.club/favicon.ico">
                  </span>
                  <span class="link">
                    <a href="https://www.xiongge.club/" target="_blank" rel="noopener">熊哥club</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/3w4fe.png">
                  </span>
                  <span class="link">
                    <a href="https://zerlong.com/" target="_blank" rel="noopener">知语</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/44hxf.png">
                  </span>
                  <span class="link">
                    <a href="http://redstonewill.com/" target="_blank" rel="noopener">红色石头</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/8g1fk.jpg">
                  </span>
                  <span class="link">
                    <a href="http://www.laodong.me/" target="_blank" rel="noopener">老董博客</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/wkaus.jpg">
                  </span>
                  <span class="link">
                    <a href="https://zhaoshuai.me/" target="_blank" rel="noopener">碎念</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/pgo0r.jpg">
                  </span>
                  <span class="link">
                    <a href="https://www.chenwenguan.com/" target="_blank" rel="noopener">陈文管的博客</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/kk82a.jpg">
                  </span>
                  <span class="link">
                    <a href="https://www.lxlinux.net/" target="_blank" rel="noopener">良许Linux教程网</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/lj0t2.jpg">
                  </span>
                  <span class="link">
                    <a href="https://tanqingbo.cn/" target="_blank" rel="noopener">IT码农</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/i8cdr.png">
                  </span>
                  <span class="link">
                    <a href="https://junyiseo.com/" target="_blank" rel="noopener">均益个人博客</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/chwv2.png">
                  </span>
                  <span class="link">
                    <a href="https://brucedone.com/" target="_blank" rel="noopener">大鱼的鱼塘</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/2y43o.png">
                  </span>
                  <span class="link">
                    <a href="http://bbs.nightteam.cn/" target="_blank" rel="noopener">夜幕爬虫安全论坛</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/zvc3w.jpg">
                  </span>
                  <span class="link">
                    <a href="https://www.weishidong.com/" target="_blank" rel="noopener">韦世东的技术专栏</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/ebudy.jpg">
                  </span>
                  <span class="link">
                    <a href="https://chuanjiabing.com/" target="_blank" rel="noopener">穿甲兵技术社区</a>
                  </span>
                </li>
              </ul>
            </div>
          </div>
        </aside>
        <div id="sidebar-dimmer"></div>
      </div>
    </main>
    <footer class="footer">
      <div class="footer-inner">
        <div class="copyright"> &copy; <span itemprop="copyrightYear">2021</span>
          <span class="with-love">
            <i class="fa fa-heart"></i>
          </span>
          <span class="author" itemprop="copyrightHolder">崔庆才丨静觅</span>
          <span class="post-meta-divider">|</span>
          <span class="post-meta-item-icon">
            <i class="fa fa-chart-area"></i>
          </span>
          <span title="站点总字数">2.6m</span>
          <span class="post-meta-divider">|</span>
          <span class="post-meta-item-icon">
            <i class="fa fa-coffee"></i>
          </span>
          <span title="站点阅读时长">39:54</span>
        </div>
        <div class="powered-by">由 <a href="https://hexo.io/" class="theme-link" rel="noopener" target="_blank">Hexo</a> & <a href="https://pisces.theme-next.org/" class="theme-link" rel="noopener" target="_blank">NexT.Pisces</a> 强力驱动 </div>
        <div class="beian"><a href="https://beian.miit.gov.cn/" rel="noopener" target="_blank">京ICP备18015597号-1 </a>
        </div>
        <script>
          (function ()
          {
            function leancloudSelector(url)
            {
              url = encodeURI(url);
              return document.getElementById(url).querySelector('.leancloud-visitors-count');
            }

            function addCount(Counter)
            {
              var visitors = document.querySelector('.leancloud_visitors');
              var url = decodeURI(visitors.id);
              var title = visitors.dataset.flagTitle;
              Counter('get', '/classes/Counter?where=' + encodeURIComponent(JSON.stringify(
              {
                url
              }))).then(response => response.json()).then((
              {
                results
              }) =>
              {
                if (results.length > 0)
                {
                  var counter = results[0];
                  leancloudSelector(url).innerText = counter.time + 1;
                  Counter('put', '/classes/Counter/' + counter.objectId,
                  {
                    time:
                    {
                      '__op': 'Increment',
                      'amount': 1
                    }
                  }).catch(error =>
                  {
                    console.error('Failed to save visitor count', error);
                  });
                }
                else
                {
                  Counter('post', '/classes/Counter',
                  {
                    title,
                    url,
                    time: 1
                  }).then(response => response.json()).then(() =>
                  {
                    leancloudSelector(url).innerText = 1;
                  }).catch(error =>
                  {
                    console.error('Failed to create', error);
                  });
                }
              }).catch(error =>
              {
                console.error('LeanCloud Counter Error', error);
              });
            }

            function showTime(Counter)
            {
              var visitors = document.querySelectorAll('.leancloud_visitors');
              var entries = [...visitors].map(element =>
              {
                return decodeURI(element.id);
              });
              Counter('get', '/classes/Counter?where=' + encodeURIComponent(JSON.stringify(
              {
                url:
                {
                  '$in': entries
                }
              }))).then(response => response.json()).then((
              {
                results
              }) =>
              {
                for (let url of entries)
                {
                  let target = results.find(item => item.url === url);
                  leancloudSelector(url).innerText = target ? target.time : 0;
                }
              }).catch(error =>
              {
                console.error('LeanCloud Counter Error', error);
              });
            }
            let
            {
              app_id,
              app_key,
              server_url
            } = {
              "enable": true,
              "app_id": "6X5dRQ0pnPWJgYy8SXOg0uID-gzGzoHsz",
              "app_key": "ziLDVEy73ne5HtFTiGstzHMS",
              "server_url": "https://6x5drq0p.lc-cn-n1-shared.com",
              "security": false
            };

            function fetchData(api_server)
            {
              var Counter = (method, url, data) =>
              {
                return fetch(`${api_server}/1.1${url}`,
                {
                  method,
                  headers:
                  {
                    'X-LC-Id': app_id,
                    'X-LC-Key': app_key,
                    'Content-Type': 'application/json',
                  },
                  body: JSON.stringify(data)
                });
              };
              if (CONFIG.page.isPost)
              {
                if (CONFIG.hostname !== location.hostname) return;
                addCount(Counter);
              }
              else if (document.querySelectorAll('.post-title-link').length >= 1)
              {
                showTime(Counter);
              }
            }
            let api_server = app_id.slice(-9) !== '-MdYXbMMI' ? server_url : `https://${app_id.slice(0, 8).toLowerCase()}.api.lncldglobal.com`;
            if (api_server)
            {
              fetchData(api_server);
            }
            else
            {
              fetch('https://app-router.leancloud.cn/2/route?appId=' + app_id).then(response => response.json()).then((
              {
                api_server
              }) =>
              {
                fetchData('https://' + api_server);
              });
            }
          })();

        </script>
      </div>
      <div class="footer-stat">
        <span id="cnzz_stat_icon_1279355174"></span>
        <script type="text/javascript">
          document.write(unescape("%3Cspan id='cnzz_stat_icon_1279355174'%3E%3C/span%3E%3Cscript src='https://v1.cnzz.com/z_stat.php%3Fid%3D1279355174%26online%3D1%26show%3Dline' type='text/javascript'%3E%3C/script%3E"));

        </script>
      </div>
    </footer>
  </div>
  <script src="//cdn.jsdelivr.net/npm/animejs@3.2.1/lib/anime.min.js"></script>
  <script src="//cdn.jsdelivr.net/npm/pangu@4/dist/browser/pangu.min.js"></script>
  <script src="/js/utils.js"></script>
  <script src="/.js"></script>
  <script src="/js/schemes/pisces.js"></script>
  <script src="/.js"></script>
  <script src="/js/next-boot.js"></script>
  <script src="/.js"></script>
  <script>
    (function ()
    {
      var canonicalURL, curProtocol;
      //Get the <link> tag
      var x = document.getElementsByTagName("link");
      //Find the last canonical URL
      if (x.length > 0)
      {
        for (i = 0; i < x.length; i++)
        {
          if (x[i].rel.toLowerCase() == 'canonical' && x[i].href)
          {
            canonicalURL = x[i].href;
          }
        }
      }
      //Get protocol
      if (!canonicalURL)
      {
        curProtocol = window.location.protocol.split(':')[0];
      }
      else
      {
        curProtocol = canonicalURL.split(':')[0];
      }
      //Get current URL if the canonical URL does not exist
      if (!canonicalURL) canonicalURL = window.location.href;
      //Assign script content. Replace current URL with the canonical URL
      ! function ()
      {
        var e = /([http|https]:\/\/[a-zA-Z0-9\_\.]+\.baidu\.com)/gi,
          r = canonicalURL,
          t = document.referrer;
        if (!e.test(r))
        {
          var n = (String(curProtocol).toLowerCase() === 'https') ? "https://sp0.baidu.com/9_Q4simg2RQJ8t7jm9iCKT-xh_/s.gif" : "//api.share.baidu.com/s.gif";
          t ? (n += "?r=" + encodeURIComponent(document.referrer), r && (n += "&l=" + r)) : r && (n += "?l=" + r);
          var i = new Image;
          i.src = n
        }
      }(window);
    })();

  </script>
  <script src="/js/local-search.js"></script>
  <script src="/.js"></script>
</body>

</html>
